题目链接:http://codeforces.com/problemset/problem/814/C
题意: 输入一个n,下一行是长度为n的字符串,再输入一个m,下面有m行,每行一个数字k一个字符c,意思是,找不是c的字符变换k次后,变成c,找最长连续的c的长度;
方法一:
用枚举法,枚举每个区间:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int ans[26][1505]; // ans[k][i] 存当变换i次时,连续字符k的最大长度;
char str[1505];
int main()
{
int i,j,k,t,n,m;
while(~scanf("%d",&n))
{
scanf("%s",str);
memset(ans,0,sizeof(ans));
for(k=0;k<26;k++)
{
for(i=0;i<n;i++) // 这层循环,和下层循环把所有的区间都枚举了一遍;
{
int tt=0;
for(j=i;j<n;j++)
{
if(str[j]!=k+'a')
tt++;
ans[k][tt]=max(ans[k][tt],j-i+1); // ans[k][tt] 当加到tt,连续的最大长度;
}
}
for ( i = 1; i <= n; i++) // 有人会说ans 数组里已经是最大值了,为什么,还要写这一步;
ans[k][i] = max(ans[k][i], ans[k][i - 1]);
// 这一步是为了 例如:有可能在枚举一个区间内只需三次变换就达到了最大,根本加不到四次
// 接着枚举时,达到了四次,ans[k][4] 里面又有值了,可能还没有ans[k][3] 时的大,所以一定要加上这一步
}
scanf("%d",&m);
while(m--)
{
char c;
scanf("%d %c",&t,&c);
printf("%d\n",ans[c-'a'][t]);
}
}
return 0;
}
方法二:
用尺取法:
反复推进开头和末尾,找取满足条件的最优解;
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char str[1505];
int main()
{
int i,j,k,n,m;
while(~scanf("%d",&n))
{
scanf("%s",str);
scanf("%d",&m);
char c;
while(m--)
{
scanf("%d %c",&k,&c);
int s=0,t=0,tt=0,ans=0; // 尺取法,枚举起点和终点,来求取满足条件的最优解;
while(1)
{
while(tt<k&&t<n)
{
if(str[t]!=c)
tt++;
t++;
}
while(t<n&&str[t]==c)
t++;
ans=max(ans,t-s);
if(t>=n) break;
while(str[s]==c)
s++;
s++;
tt--;
}
printf("%d\n",ans);
}
}
return 0;
}