题目:
https://www.luogu.org/problem/show?pid=1203
标签是搜索和动态规划……;
O(n^2)纯模拟;
这个题交了三遍才A;
思路:
记两个数组;Next和pre;
然后模拟;
坑:
1.第一次交56分,没有判全是相同的情况,以及走重的情况;
2.第二次交67分,因为没有考虑以w为起点的情况;
当以w为起点是,它可以看做r,也可以看做b,需要分别计数;
总结:
1.要想全情况;
2.读准题意!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1001;
int n,sta,en,ans,cnt;
int Next[MAXN],pre[MAXN];
bool vis[MAXN];
char s[MAXN],c;
void init()
{
for(int i=2;i<n;i++) Next[i]=i+1,pre[i]=i-1;
Next[n]=1,Next[1]=2,pre[1]=n,pre[n]=n-1;
}
void calc(int k)
{
for(int j=k;;j=Next[j])
{
if(!vis[j] && (s[j]==c || s[j]=='w')) vis[j]=1,cnt++;
// else if(!vis[j] && c=='w') vis[j]=1,cnt++;
else break;
}
c=s[pre[k]];//并不是i-1,因为1也可以和n作为断开点;
for(int j=pre[k];;j=pre[j])
{
if(!vis[j] && (s[j]==c || s[j]=='w')) vis[j]=1,cnt++;
// else if(!vis[j] && c=='w') vis[j]=1,cnt++;
else break;
}
}
void solve()
{
scanf("%d%s",&n,s+1);
init();
int len=strlen(s+1);
for(int i=1;i<=n;i++)//枚举断开点;
{
memset(vis,0,sizeof(vis));
c=s[i],cnt=0;
if(c=='w')
{
c='r',calc(i);
memset(vis,0,sizeof(vis)),cnt=0;
c='b',calc(i);
}
else calc(i);
ans=max(ans,cnt);
if(cnt==n) break;
}
cout<<ans;
}
int main()
{
solve();
return 0;
}