问题描述
你有一条项链,它由 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
Figure A Figure B
r red bead
b blue bead
w white bead
项链上的第一个和第二个珠子已经在图中标出了。
图 A 也可以用一个由 b 和 r 组成的字符串直接表示,b 代表蓝色而 r 代表红色,如下所示:brbrrrbbbrrrrrbrrbbrbbbbrrrrb。
假设你想从项链的某处将它截断拉直;接着从一端向另外一端数收集同颜色的珠子,直到碰到一个不同颜色的珠子为止;然后再从另外一端做同样的操作。(一端收集的珠子颜色可以不同于另一端的。)
请想办法找到一个截断项链的位置,能够让我们尽量多地收集到同色的珠子。
例子
如图 A 中的项链,从第 9 和第 10 个或者第 24 和 第 25 个珠子中间截断,则我们可以收集到 8 个珠子。
图 B 中的项链有白色的珠子,当遇到白色的珠子时,它既可以作为蓝色的珠子看待,也可以作为红色的珠子看待,由收集珠子时的需求决定。包含有白色珠子的项链则会由 r、b 和 w 字符组成的字符串来表示。
请编写一个程序计算从某条项链中能够收集到多少个珠子。
输入格式
第一行: N,项链上珠子的个数
第二行:一个字符串,长度为 N,由 r、b 和 w字符组成
输入样例
29 wwwbbrwrbrbrrbrbrwrwwrbwrwrrb
输出格式
输出一行字符,它应该包含了计算出的结果。
输出样例
11
整体思路:
整体思路就是遍搜,找出可以收集到的珠子的最大个数,从开始找断点然后分别向两边进行搜索。珠子的情况大致可以分为三种,一种是全部为W,一种是全部为B或是R,还有一种就是这三种颜色的珠子混合存在。
具体方法:
具体方法其实就是怎么实现珠子连在一起的问题,如果直接做的话可以这样:
(1)在循环的时候,循环变量一旦减到负数就加上n,一旦加到n就减去n。
(2)也可以把原来的字符串复制一次或是两次到一个叔组里面,然后就不用考虑最后的链接问题了,每一次只要在i~i+n之间循环就可以了。
具体循环的时候就是左边找一遍然后右边找一遍,然后把左右两边的珠子数加在一起,但是存在全部是R或是全部是B或是全为W和R混或是全为W和B混合,所以在从一边向另一边记录的时候最好设置一个变量,意思就是左边已经搜索过的,右边就不用再搜索了,这样就可以防止最后的结果大于n。
然后每次搜索过后的结果都和Max比较,让Max取最大值就好了,最后输出Max即可。
实现代码
<span style="font-family:Microsoft YaHei;font-size:14px;">#include<stdio.h>
#include<string.h>
int main()
{
char tem[710];
int i,j,n,p,m,k=1;
char temp,linshi;
int countleft,countright,max=0,countleft1,countright1,count;
scanf("%d",&n);
getchar();
for(i=0;i<n;i++)
{
scanf("%c",&tem[i]);
tem[i+n]=tem[i];
}
for(i=0;i<n;i++)
{
if(tem[i]!='w')
{
k=0;
break;
}
}
if(k==1)
{
printf("%d\n",n);
}
else
{
for(i=0;i<n;i++)
{
countleft=0;
countleft1=0;
countright=0;
countright1=0;
count=0;
m=0;
if(tem[i+1]=='w')
{
for(j=i+1;j<=i+n;j++)
{
if(tem[j]=='w')
{
countleft1++;
}
else
{
p=j;
break;
}
}
linshi=tem[p];
for(j=p;j<=i+n;j++)
{
if(tem[j]=='w'||tem[j]==linshi)
{
countleft++;
m=j+1;
}
else
{
m=j;
break;
}
}
countleft+=countleft1;
}
if(tem[i+1]!='w')
{
linshi=tem[i+1];
for(j=i+1;j<=i+n;j++)
{
if(tem[j]=='w'||tem[j]==linshi)
{
countleft++;
m=j+1;
}
else
{
m=j;
break;
}
}
}
if(tem[i]=='w')
{
for(j=i+n;j>=m;j--)
{
if(tem[j]=='w')
{
countright1++;
}
else
{
p=j;
break;
}
}
linshi=tem[p];
for(j=p;j>=m;j--)
{
if(tem[j]=='w'||tem[j]==linshi)
{
countright++;
}
else
{
break;
}
}
countright+=countright1;
}
if(tem[i]!='w')
{
linshi=tem[i];
for(j=i+n;j>=m;j--)
{
if(tem[j]=='w'||tem[j]==linshi)
{
countright++;
}
else
{
break;
}
}
}
count=countleft+countright;
if(max<count)
{
max=count;
}
}
printf("%d\n",max);
}
return 0;
}</span>