USACO-Section1.1 Broken Necklace

来源:互联网 发布:大连淘宝客服 双休 编辑:程序博客网 时间:2024/05/16 23:51

2017-05-25

题目大意:

你有一条由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假如你要在一些点打破项链,展开成一条直线,然后从一端开始收集同颜色的珠子直到你遇到一个不同的颜色珠子,在另一端做同样的事(颜色可能与在这之前收集的不同)。 确定应该在哪里打破项链来收集到最大数目的珠子。例如,在图片 A 中的项链中,在珠子 9 和珠子 10 或珠子 24 和珠子 25 之间打断项链可以收集到8个珠子。白色珠子什么意思?在一些项链中还包括白色的珠子(如图片B) 所示。当收集珠子的时候,一个被遇到的白色珠子可以被当做红色也可以被当做蓝色。表现含有白珠项链的字符串将会包括三个符号 r , b 和 w 。写一个程序来确定从一条被给出的项链可以收集到的珠子最大数目。

样例输入:

29 wwwbbrwrbrbrrbrbrwrwwrbwrwrrb

样例输出:

11

题解:

因为珠子是圆环,因此将其在1位置切开并在首尾各加一串一样的珠子。然后开始尝试len - 1中切法,每一种切法又分为切口左右两边都不是'w'和左右两边有'w'的情况。然后分别查找两边最长的符合条件的串长。

代码:

    #include<iostream>    #include<fstream>    #include<cstring>    using namespace std;    int main(){        ofstream cout("beads.out");        ifstream cin("beads.in");        char ch[1500];        char c[360];        int len;        cin >> len;        cin >> c;        int len1,len2,tmp1,tmp2;        int maxlen = 0;        char flag1,flag2; //记录从切口往两边走遇到的第一个有颜色的珠子颜色        for(int i = 0;i < len;i++){ //两边分别加了一串相同的珠子            ch[i] = c[i];            ch[len + i] = c[i];            ch[2*len + i] = c[i];        }        for(int i = len;i <= 2 * len;i++){ // 尝试len - 1种切法            tmp1 = i - 1;            tmp2 = i;            len1 = 0;            len2 = 0;            flag1 = ch[i - 1];            flag2 = ch[i];            if(flag1 == 'w'){ //如果遇到的珠子是白色,则需要从找标记颜色                while(tmp1 >= 0 && ch[tmp1] == 'w'){                    tmp1--;len1++;                }                flag1 = ch[tmp1];            }             while(ch[tmp1] == flag1 || ch[tmp1] == 'w'){ //确认标记后,找最长的符合要求的串长                tmp1--;                len1++;            }            if(flag2 == 'w'){                while(tmp2 <= 3 * len && ch[tmp2] == 'w'){                    tmp2++;len2++;                }                flag2 = ch[tmp2];            }             while(ch[tmp2] == flag2 || ch[tmp2] == 'w'){                tmp2++;                len2++;            }             if((len1+len2) <= len)                 maxlen = max(maxlen , (len1 + len2));            else // 如果两边长度加起来超过原来珠子的长度,答案就直接是原来珠子的长度                maxlen = len;        }        cout << maxlen << endl;        return 0;    } 
原创粉丝点击