CodeForces

来源:互联网 发布:com域名注册局 编辑:程序博客网 时间:2024/06/06 17:52

题目链接: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;}