六一儿童节到了,小朋友们在玩丢手绢的游戏。总共有C个小朋友,编号从1到C,他们站成一个圈,第i(1<i<=C)个人的左边是i-1,第1个人的左边是C。第i(1<=i<C)个人的右边是i+1,第C个人的右边是1。然后再给出一个常数E。刚开始的时候1号小朋友拿着手绢,接下来游戏开始,在游戏的每一轮,拿手绢的人会把手绢向右边传递E-1个人,拿到手绢的人退出圈,把手绢递给他右边的小朋友,剩下的人向中间挨紧,把圈中的空位补满。然后开始下一轮,如此往复。直到圈中只剩一个人。比如C=6,E=5的时候,出圈的顺序是5,4,6,2,3,最后1号小朋友留在了圈中。
现在有2G个小朋友,要求一个最小的常数E,使得这2G个小朋友玩了G轮游戏之后,出圈的小朋友编号刚好是G+1到2G。
Input
多组测试数据。 每一行给出一个整数G( 0 < G < 14),G=0的时候表示输入结束。
Output
输出多行,表示每一组数据的答案。
Input示例
3 4 0
Output示例
5 30
此题我没有发现任何技巧,所以我选择打表
12,13跑了有半个小时还要多
1 #include <cctype> 2 #include <cstdio> 3 4 const int MAXN=30; 5 6 int n; 7 8 int next[MAXN],from[MAXN],f[MAXN]; 9 10 inline bool pd(int num,int x) { 11 for(int i=2;i<2*x;++i) next[i]=i+1,from[i]=i-1; 12 next[1]=2;from[1]=x*2;next[2*x]=1;from[x*2]=2*x-1; 13 int i=1,t=1,s=2*x; 14 while(s>x) { 15 if(t==num) { 16 if(i<=x) return false; 17 int p=from[i]; 18 int nx=next[i]; 19 next[p]=nx;from[nx]=p; 20 --s; 21 t=1;i=nx; 22 } 23 i=next[i]; 24 ++t; 25 } 26 return true; 27 } 28 29 int hh() { 30 f[1]=2; 31 for(int i=2;i<=14;++i) { 32 for(int j=i+1;;++j) 33 if(pd(j,i)) {f[i]=j;printf("%d ",f[i]);break;} 34 } 35 for(int i=1;i<=14;++i) printf("%d ",f[i]); 36 return 0; 37 } 38 39 int sb=hh(); 40 int main(int argc,char**argv) {;}
打表程序
1 #include <cctype> 2 #include <cstdio> 3 4 const int MAXN=14; 5 6 int n; 7 8 int f[MAXN]={0,2,7,5,30,169,441,1872,7632,1740,93313,459901,1358657,2504881}; 9 10 int hh() { 11 while(scanf("%d",&n)) { 12 if(n==0) break; 13 printf("%d ",f[n]); 14 } 15 return 0; 16 } 17 18 int sb=hh(); 19 int main(int argc,char**argv) {;}
标程