训练赛第一场A题 (ZOJ 2313)
解题报告:n个人围坐成一圈,并且将这n个人从1到n编号,然后编号为1 的人手上有一个物品,将这个物品往向左传递给第k个人,1<=k<=n/2,当这个物品再次传到编号为1 的人的手上时,游戏结束,要使这个k最大,并且,在游戏结束后要求每一个人都要拿过这个物品,求这个最大的k。
看了一下就猜想大概就是在n/2附近去找,然后做了几个小的数字分析了一下,发现猜想没有错误,不过不能证明,这题还有一个到现在还是很困惑的地方,为什么我的代码数组一定要开到20000,本来开到2000就够了,但我的一定要开到20000,就因为这个比赛的时候卡了很久。希望知道的大牛给我留个言。
下面将这几种情况列出来:
1.n & 1 == 1 ans = n / 2;
2.n & 1 == 0 && n / 2 % 2 == 1 ans = n / 2 - 2;
3.n & 1 == 0 && n / 2 % 2 == 0 ans = n / 2 - 1;
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 6 char* chu(char *s) 7 { 8 int len = strlen(s),f = 0; 9 char t[4005]; 10 int left = 0; 11 for(int i = 0;i<len;++i) 12 { 13 int x = 10*left + s[i] - '0'; 14 t[f++] = x / 2 + '0'; 15 if((s[i]-'0') & 1) 16 left = 1; 17 else left = 0; 18 } 19 t[f] = NULL; 20 if(t[0] == '0') 21 return t+1; 22 return t; 23 } 24 25 char* sub2(char *s) 26 { 27 int len = strlen(s); 28 int l = len - 1; 29 while(l >= 0) 30 { 31 if((s[l] - '0') != 0) 32 { 33 s[l] -= 1; 34 break; 35 } 36 else s[l] = '9'; 37 l--; 38 } 39 if(s[0] == '0') 40 return s+1; 41 return s; 42 } 43 44 int main() 45 { 46 int T,te = 0; 47 scanf("%d",&T); 48 while(T--) 49 { 50 char str[4005],temp[4005]; 51 scanf("%s",str); 52 int len = strlen(str); 53 if((str[len-1]-'0') & 1) 54 { 55 str[len-1] -= 1; 56 char *ans = chu(str); 57 printf("%s\n",ans); 58 } 59 else 60 { 61 char *an = chu(str); 62 an = sub2(an); 63 int len2 = strlen(an); 64 if((an[len2-1] -'0') & 1) 65 printf("%s\n",an); 66 else 67 { 68 an = sub2(an); 69 printf("%s\n",an); 70 } 71 } 72 if(T != 0) 73 printf("\n"); 74 } 75 return 0; 76 } 77