USACO 1.1.4 Broken Necklace

//译题
★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 }
原文地址:https://www.cnblogs.com/Lee-geeker/p/3223191.html