//译题 ★Broken Necklace 破碎的项链 你有一条由N 个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里 是 n=29 的二个例子: 1 2 1 2 r b b r b r r b r b b b r r b r r r w r b r w w b b r r b b b b b b r b r r b r b r r r b r r r r r r b r b r r r w 图片 A 图片 B r 代表 红色的珠子 b 代表 蓝色的珠子 w 代表 白色的珠子 第一和第二个珠子在图片中已经被作记号. 图片 A 中的项链可以用下面的字符串表示: brbrrrbbbrrrrrbrrbbrbbbbrrrrb . 假如你要在一些点打破项链,展开成一条直线,然后从一端开始收集同颜色的珠子直到你遇到一个 不同的颜色珠子,在另一端做同样的事.(颜色可能与在这之前收集的不同) 确定应该在哪里打破项 链来收集到最大多数的数目的子. Example 举例来说,在图片 A 中的项链,可以收集到8 个珠子, 在珠子 9 和珠子 10 或珠子 24 和珠子 25 之间打断项链. 在一些项链中,包括白色的珠子如图 片 B 所示. 当收集珠子的时候,一个被遇到的白色珠子可以被当做红色也可以被当做蓝色. 表现 项链的字符串将会包括三符号 r , b 和 w . 写一个程序来确定从一条被供应的项链最大可以被收 集珠子数目. PROGRAM NAME: beads INPUT FORMAT 第 1 行: N, 珠子的数目 第 2 行: 一串度为N 的字符串, 每个字符是 r , b 或 w. SAMPLE INPUT (file beads.in) 29 wwwbbrwrbrbrrbrbrwrwwrbwrwrrb OUTPUT FORMAT 单独的一行包含从被供应的项链可以被收集的珠子数目的最大值. SAMPLE OUTPUT (file beads.out) 11
/* ID: china_l5 LANG: C TASK:beads */ #include<stdio.h> #include<string.h> #define MAX (350 + 10) int main() { freopen("beads.in", "r", stdin); freopen("beads.out", "w", stdout); int i, j, N, T; int max=0, count1, count2; char s[MAX*2], str[MAX], tmp; memset(s,0,sizeof(s)); scanf("%d",&N); //读入N getchar(); //如果没有这句,接受完会跳过下面的gets(str); gets(str); strcpy(s,str); //复制字符串 strcat(s,str); //连接字符串 ,将环转化为链 /* 或者使用下面方法将一个字符串存两遍使得环转化为链。 scanf("%d %s",&N, s); for(i=0;i<N;i++) s[i+N] = s[i]; */ //这里使用的是模拟的方法来做,将一条项链用数组存两次, //然后对每一个可能的断开点进行从左到又和从右到左两次扫描, //最后算出count1 + count2 的最大值,即为所求。 for(i=0;i<N;i++) //一条链的长度 ,分别对每一个断点进行测试 { count1=count2=0; //分别记录最大珠子数 T=N+i-1; //与I相对应的T for(j=i; ;j++) //从左往右扫 { if(s[j]!='w') { tmp = s[j]; //先找到从左开始第一个不是 w 的字符,然后用tmp存起来 break; } count1++; } for( ;j<=T;j++) { if(s[j] == 'w') { count1++; continue; } else if(s[j] == tmp) { count1++; continue; } break; } for(j=T; ;j--) //从右往左扫 { if(s[j]!='w') //先找到从右开始第一个不是 w 的字符,然后用tmp存起来 { tmp =s[j]; break; } count2++; } for( ;j>=i;j--) //然后继续扫描 { if(s[j] == 'w') //如果是‘w’,count+1; 继续循环 { count2++; continue; } else if(s[j] == tmp) //如果字符和tmp相等,count+1,继续循环 { count2++; continue; } break; } max=(max>(count1+count2))?max:(count1+count2); // printf("%d %d %d ",max,count1,count2); 可以用这句来查看count1,count2 和 max } if(max>N) max = N; printf("%d ", max); return 0; }
精简后的代码
1 /* 2 ID: china_l5 3 LANG: C 4 TASK:beads 5 */ 6 #include<stdio.h> 7 #include<string.h> 8 #define MAX (350 + 10) 9 10 int main() 11 { 12 freopen("beads.in", "r", stdin); 13 freopen("beads.out", "w", stdout); 14 15 int i, j, N, T; 16 int max=0, count1, count2; 17 char s[MAX*2], str[MAX], tmp; 18 memset(s,0,sizeof(s)); 19 20 scanf("%d",&N); 21 getchar(); 22 gets(str); 23 strcpy(s,str); 24 strcat(s,str); 25 26 for(i=0;i<N;i++) 27 { 28 count1=count2=0; 29 T=N+i-1; 30 for(j=i; ;j++) 31 { 32 if(s[j]!='w') 33 { 34 tmp = s[j]; 35 break; 36 } 37 count1++; 38 } 39 for( ;j<=T;j++) 40 { 41 if(s[j]!=tmp && s[j]!='w') 42 break; 43 count1++; 44 } 45 46 for(j=T; ;j--) 47 { 48 if(s[j]!='w') 49 { 50 tmp =s[j]; 51 break; 52 } 53 count2++; 54 } 55 for( ;j>=i;j--) 56 { 57 if(s[j]!=tmp && s[j]!='w') 58 break; 59 count2++; 60 } 61 max=(max>(count1+count2))?max:(count1+count2); 62 } 63 if(max>N) max = N; 64 printf("%d ", max); 65 return 0; 66 }