1.1.4 Broken Necklace

来源:互联网 发布:淘宝助理图片效验出错 编辑:程序博客网 时间:2024/06/11 01:04

Description

你有一条由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 。 写一个程序来确定从一条被给出的项链可以收集到的最大珠子数目。
Input

第 1 行: N, 珠子的数目 第 2 行: 一串长度为N的字符串, 每个字符是 r , b 或 w。

Output

单独的一行包含从被供应的项链可以被收集的珠子数目的最大值。

Sample Input

29
wwwbbrwrbrbrrbrbrwrwwrbwrwrrb
Sample Output
11

这个题好麻烦!改了一下午的代码才改对。
代码写的很乱!
当天做的题应当天写题解的!因为懒…竟然推了半个月,再回来看代码,一头迷雾!

回忆回忆:当时的思路是对于每一个字符都向前和向后遍历,如果满足题目中条件就继续遍历,否则就开始下一个字符的遍历。每次遍历的时候都统计下珠子的数量,找出最大值。
我是用数组模拟写的,最难处理的部分就是遍历到数组的尾部和头部的时候交接的问题,好多细节。
我感觉用循环链表去写可能会更简单点。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<stack>using namespace std;int Max(int a,int b){    return a>b?a:b;}int main(){    int n;    char str[400];    scanf("%d",&n);    scanf("%s",str+1);    int ans=0;    int i,j,k;    int len=n;    for(i=1; i<=len; i++)    {        stack<char>s1;        stack<char>s2;//这两个栈用来存向前向后遍历时满足条件的字符        int num1=0,num2=0;        int flag1=0,flag2=0;        char ch1,ch2;        j=i,k=i+1;        if(k==len+1)//先预处理一下遍历最后一个字符时的情况。        {            k=1;            flag2=1;        }        s1.push(str[j]);        s2.push(str[k]);        int mark1=0,mark2=0;        while(j!=i||k!=i)        {            j--,k++;            if(j==0)//处理遍历到头部的情况            {                j=len;                flag1=1;            }            if(k==len+1)//处理遍历到尾部的情况            {                k=1;                flag2=1;            }            if(j==k)//处理遍历时两个正好相遇的情况            {                if(str[j]=='w')                    num1++;                else if(str[j]==s1.top())                    s1.push(str[j]);                else if(str[k]==s2.top())                    s2.push(str[k]);                break;            }            //以下是各种处理break            if(flag1&&flag2)                break;            if(flag1&&j<k)                break;            if(flag2&&j<k)                break;            if(j==i)                mark1=1;            if(k==i)                mark2=1;            if(!mark1)            {                if(str[j]==s1.top())                    s1.push(str[j]);                else if(str[j]=='w')                    num1++;                else                    mark1=1;            }            if(!mark2)            {                if(str[k]==s2.top())                    s2.push(str[k]);                else if(str[k]=='w')                    num2++;                else                    mark2=1;            }            if(mark1&&mark2)                break;        }        ans=Max(ans,s1.size()+s2.size()+num1+num2);//找出最大值    }    cout<<ans<<endl;}

代码写的实在是糟糕,
踩一下自己。

原创粉丝点击