USACO 1.1.4 Broken Necklace

来源:互联网 发布:telnet 端口失败解决 编辑:程序博客网 时间:2024/05/22 03:08

USACO 1.1.4  BrokenNecklace

     题意:有一条由三种字符组成的项链,从某个字符开始像两个方向找具有相同颜色的连续的珠子,这两个方向找的珠子的颜色可以不同,白色的珠子可以被当做红色的或绿色的。问从某一处断开这样找,最多能找到多少个珠子。

     被说是USACO上第一道不是智障的题目。换了好多种思路,最后在网络上发现了一种超赞的。就是对每个珠子来说,它的左右两边的两种颜色的连续的珠子的数目只有两种情况,要么是 0 ,要么是它前面的那个珠子的连续数目+1 ,遇到白色的珠子那就是前面那颗珠子的两种颜色的连续数都+ 1。再注意些细节就好。

     细节+代码:

 

    

/*ID: 15257142LANG: CTASK: beads*/#include<stdio.h>#include<string.h>int main(){freopen("beads.in","r",stdin); /*哦哼!天知道这根本不是USACO交题示范的函数。*/freopen("beads.out","w",stdout);int n,m,f,t,i,MAX;char a[800],b[800],mark;int bl[800],rl[800],rr[800],br[800];scanf("%d",&n);scanf("%s",a);strcpy(b,a);strcat(a,b); /*为了把同样的项链粘在之前的项链上,*/m = strlen(a)-1; /*这思路很基本。*/f = 1;t = 0;for(i = 0;i<=m;i++){if(a[i]=='w'&&t==0){mark = a[i];continue;}if(a[i]!='w'&&t==0){mark = a[i];t = 1;continue;}if(a[i]!=mark&&a[i]!='w'){f = 0;break;}}if(f==1){printf("%d\n",n);fclose(stdin);fclose(stdout);return 0;}for(i = 0;i<=m;i++){if(i==0){if(a[i]=='b'){bl[i] = 1;rl[i] = 0;}if(a[i]=='r'){bl[i] = 0;rl[i] = 1;}if(a[i]=='w'){bl[i] = 1;rl[i] = 1;}continue;}if(a[i]=='b'){bl[i] = bl[i-1]+1;rl[i] = 0;}if(a[i]=='r'){bl[i] = 0;rl[i] = rl[i-1]+1;}if(a[i]=='w'){bl[i] = bl[i-1]+1;rl[i] = rl[i-1]+1;}}for(i = m;i>=0;i--){if(i==m){if(a[i]=='b'){br[i] = 1;rr[i] = 0;}if(a[i]=='r'){br[i] = 0;rr[i] = 1;}if(a[i]=='w'){br[i] = 1;rr[i] = 1;}continue;}if(a[i]=='b'){br[i] = br[i+1]+1;rr[i] = 0;}if(a[i]=='r'){br[i] = 0;rr[i] = rr[i+1]+1;}if(a[i]=='w'){br[i] = br[i+1]+1;rr[i] = rr[i+1]+1;}}MAX = 0;for(i = 0;i<=m-1;i++){if(bl[i]+rr[i+1]>MAX)MAX = bl[i]+rr[i+1];if(rl[i]+br[i+1]>MAX)MAX = rl[i]+br[i+1];}if(MAX>n) /*如果有重复计数,必然已经绕过一圈,所以。*/MAX = n;printf("%d\n",MAX);fclose(stdin);fclose(stdout);return 0;}