今天做了一道题,提交好几次才勉强成功,在这里记录一下。
题目链接
错误1.向左遍历完后没考虑到当前在最后一个字符后面的情况
提交记录1
代码:
#include <cstdio>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
string s;
int take(const int i,const int len){ //从第i个后面开始,字符串长度为len
int j=i,cnt=0;
char comp=s[i],tmp=comp; //tmp:第一个“被比较”字符
while(s[j]==comp||s[j]=='w'){ //向左
cnt++;
j--;
if(j<0)
j=len-1;
if((s[j+1]=='w'&&j!=len-1&&tmp=='w')||(j==len-1&&s[0]=='w'&&tmp=='w'))
comp=s[j];
}
j=i+1;
comp=s[i+1]; //错误
while(s[j]==comp||s[j]=='w'){ //向右
cnt++;
j++;
if(j>len-1)
j=0;
if((s[j-1]=='w'&&j!=0&&tmp=='w')||(j==0&&s[len-1]=='w'&&tmp=='w'))
comp=s[j];
}
return cnt;
}
int main(){
int n;
scanf("%d",&n);
getchar();
cin>>s;
int len=s.length(),maxlen=0;
for(int i=0;i<len;i++){ //第i个后面
int x=take(i,len);
//printf("%d %d\n",i,x);
maxlen=max(maxlen,x);
}
printf("%d",maxlen);
return 0;
}
错误2.没考虑字符串有较多重复字符的情况
提交记录2
代码:
#include <cstdio>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
string s;
//错误,没考虑字符串有较多重复字符的情况
int take(const int i,const int len){ //从第i个后面开始,字符串长度为len
int j=i,cnt=0;
char comp=s[i],tmp=comp; //tmp:第一个“被比较”字符
while(s[j]==comp||s[j]=='w'){ //向左
cnt++;
j--;
if(j<0)
j=len-1;
if((s[j+1]=='w'&&j!=len-1&&tmp=='w')||(j==len-1&&s[0]=='w'&&tmp=='w')) //第一个“被比较”字符必须为w才能更新
comp=s[j];
}
if(i==len-1){ //考虑到当前在最后一个字符后面的情况
j=0;
comp=s[0];
}
else{
j=i+1;
comp=s[i+1];
}
tmp=comp;
while(s[j]==comp||s[j]=='w'){ //向右
cnt++;
j++;
if(j>len-1)
j=0;
if((s[j-1]=='w'&&j!=0&&tmp=='w')||(j==0&&s[len-1]=='w'&&tmp=='w'))
comp=s[j];
}
return cnt;
}
int main(){
int n;
scanf("%d",&n);
getchar();
cin>>s;
int len=s.length(),maxlen=0;
for(int i=0;i<len;i++){ //第i个后面
int x=take(i,len);
maxlen=max(maxlen,x);
if(maxlen==len)
break;
}
printf("%d",maxlen);
return 0;
}
解决思路:限定循环次数
错误3.一次遍历中可能多次更新comp
提交记录3
代码:
#include <cstdio>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
string s;
int take(const int i,const int len){ //从第i个后面开始,字符串长度为len
int j=i,cnt=0,tme=0; //tme 循环次数
char comp=s[i],tmp=comp; //tmp 第一个“被比较”字符
while(tme<=len&&(s[j]==comp||s[j]=='w')){ //向左
cnt++;
j--;
tme++;
if(j<0)
j=len-1;
if((s[j+1]=='w'&&j!=len-1&&tmp=='w')||(j==len-1&&s[0]=='w'&&tmp=='w'))
comp=s[j];
}
if(i==len-1){ //当前在最后一个字符后面的情况
j=0;
comp=s[0];
}
else{
j=i+1;
comp=s[i+1];
}
tmp=comp,tme=0;
while(tme<=len&&(s[j]==comp||s[j]=='w')){ //向右
cnt++;
j++;
tme++;
if(j>len-1)
j=0;
if((s[j-1]=='w'&&j!=0&&tmp=='w')||(j==0&&s[len-1]=='w'&&tmp=='w'))
comp=s[j];
}
return cnt;
}
int main(){
int n;
scanf("%d",&n);
getchar();
cin>>s;
int len=s.length(),maxlen=0;
for(int i=0;i<len;i++){ //第i个后面
int x=take(i,len);
maxlen=max(maxlen,x);
if(maxlen==len)
break;
if(maxlen>len) //最长为字符串长度
maxlen=len;
}
printf("%d",maxlen);
return 0;
}
错误4.说实话这次我也不知道错在哪了……
提交记录4
代码:
#include <cstdio>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
string s;
int take(const int i,const int len){ //从第i个后面开始,字符串长度为len
int j=i,cnt=0,tme=0; //tme为循环次数,不要写成time
char comp=s[i],tmp=comp; //tmp:第一个“被比较”字符
while(tme<=len&&(s[j]==comp||s[j]=='w')){ //向左
if((s[j]=='w'&&j!=0&&tmp=='w')||(j==0&&s[len-1]=='w'&&tmp=='w'))
comp=s[j];
cnt++;
j--;
tme++;
if(j<0)
j=len-1;
}
if(i==len-1){ //考虑到当前在最后一个字符后面的情况
j=0;
comp=s[0];
}
else{
j=i+1;
comp=s[i+1];
}
tmp=comp,tme=cnt;
while(tme<=len&&(s[j]==comp||s[j]=='w')){ //向右
if((s[j]=='w'&&j!=len-1&&tmp=='w')||(j==len-1&&s[0]=='w'&&tmp=='w'))
comp=s[j];
cnt++;
j++;
tme++;
if(j>len-1)
j=0;
}
return cnt;
}
int main(){
int len,maxlen=0;
scanf("%d",&len);
getchar();
cin>>s;
for(int i=0;i<len;i++){
int x=take(i,len);
maxlen=max(maxlen,x);
if(maxlen==len)
break;
}
if(maxlen>len) //最长为字符串长度
maxlen=len;
printf("%d",maxlen);
return 0;
}
参考思路:遇到w时分别把w改成r和b求解,最后改回来
参考代码:
#include <iostream>
#include <algorithm>
using namespace std;
string a;
int f(int x)
{
int s=0;
char a1=a[x];
char b2=a[x+1];
for(int i=x;;i--)//往前看和往后看
{
if(a[i]==a1)s++;
else if(a[i]=='w')
s++;
else
break;
}
for(int i=x+1;;i++)
{
if(a[i]==b2)s++;
else if(a[i]=='w')
s++;
else
break;
}
return s;
}
int main()
{
int ans,n;
ans=-1;
cin>>n;
cin>>a;
a=a+a+a;
for(int i=n;i<2*n;i++)//三段 从中间那一段开始处理,左右两边分别处理左越界与右越界的情况
{
if(a[i]==a[i+1])
continue;
if(a[i]=='w')//如果当前为w,就把当前字符分别改为b和r,最后要改回来
{
a[i]='r';
ans=max(ans,f(i));
a[i]='b';
ans=max(ans,f(i));
a[i]='w';
}
ans=max(ans,f(i));
}
ans=min(ans,n);//最长也不能比总长长
if(ans==-1)ans=n;//出现这种情况必定是一路continue过来的
cout<<ans;
return 0;
}