Vijos 约瑟夫问题10E100版 (又是找规律+高精)
描述
n个人排成一圈。从某个人开始,按顺时针方向依次编号。从编号为1的人开始顺时针“一二一”报数,报到2的人退出圈子。这样不断循环下去,圈子里的人将不断减少。由于人的个数是有限的,因此最终会剩下一个人。试问最后剩下的人最开始的编号。
格式
输入格式
一个正整数n,表示人的个数。输入数据保证数字n不超过100位。
输出格式
一个正整数。它表示经过“一二一”报数后最后剩下的人的编号。
样例1
样例输入1
9
样例输出1
3
限制
各个测试点1s
提示
样例说明
当n=9时,退出圈子的人的编号依次为:
2 4 6 8 1 5 9 7
最后剩下的人编号为3
来源
Matrix67 根据经典问题改编
先打个表找规律
1 #include<cstdio> 2 #include<ctime> 3 #include<cstring> 4 int vis[10001]= {0}; 5 int main() { 6 freopen("output.txt","w",stdout); 7 for(int z=1; z<=10000; z++) { 8 memset(vis,0,sizeof(vis)); 9 int n,count=0; 10 n=z; 11 int now=1,next=1,kill=0; 12 while(count<n-1) { 13 do 14 next=(next-1+1)%n+1; 15 while(vis[next]); 16 if(kill) { 17 count++; 18 vis[now]=1; 19 kill=0; 20 } else 21 kill=1; 22 now=next; 23 } 24 for(int i=1; i<=n; i++) 25 if(!vis[i]) 26 printf("%d,",i); 27 } 28 return 0; 29 }
找到规律后 再用高精 (有点恶心)
1 /* 2 当 2^i<=n<=2^(i+1) 时 3 输出 (n-2^i)*2+1 4 */ 5 #include<cstdio> 6 #include<cstring> 7 #include<iostream> 8 #define MAXN 1010 9 10 using namespace std; 11 12 int a[MAXN],y[MAXN],b[MAXN],c[MAXN],cnt; 13 14 char s[MAXN]; 15 16 inline void chuli() { 17 int len=strlen(s); 18 y[0]=len; 19 for(int i=len-1;i>=0;i--) y[++cnt]=s[i]-48; 20 } 21 22 inline bool pd() { 23 if(y[0]>a[0]) return false; 24 else if(y[0]<a[0]) return true; 25 else { 26 for(int i=y[0];i>=1;i--) { 27 if(y[i]>a[i]) return false; 28 if(y[i]<a[i]) return true; 29 } 30 } 31 return false; 32 } 33 34 inline void mul() { 35 for(int i=0;i<=a[0];i++) b[i]=a[i]; 36 a[0]++; 37 for(int i=1;i<=a[0];i++) a[i]*=2; 38 for(int i=1;i<=a[0];i++) { 39 if(a[i]>=10) { 40 a[i+1]+=a[i]/10; 41 a[i]%=10; 42 } 43 } 44 while(a[0]>0&&!a[a[0]]) a[0]--; 45 } 46 47 inline void div() { 48 c[0]=y[0]; 49 for(int i=1;i<=y[0];i++) { 50 c[i]+=y[i]-b[i]; 51 if(c[i]<0) { 52 c[i+1]--; 53 c[i]+=10; 54 } 55 } 56 while(c[0]>0&&!c[c[0]]) c[0]--; 57 memset(a,0,sizeof a); 58 for(int i=0;i<=c[0];i++) a[i]=c[i]; 59 } 60 61 int main() { 62 cin>>s; 63 chuli(); 64 a[0]=1; 65 a[1]=1; 66 while(!pd()) mul(); 67 div(); 68 mul(); 69 if(!a[0]) a[0]++; 70 a[1]++; 71 for(int i=1;i<=a[0];i++) { 72 if(a[i]>=10) { 73 if(i==a[0]) a[0]++; 74 a[i+1]+=a[i]/10; 75 a[i]%=10; 76 } 77 } 78 while(a[0]>0&&!a[a[0]]) a[0]--; 79 for(int i=a[0];i>=1;i--) printf("%d",a[i]); 80 printf("\n"); 81 return 0; 82 }
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现