目录
题目1 : Same Letters In A Row
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
Litter Ho has a string of lowercase letters. He wants to re-order the letters so that the same letters are placed together in a row.
Unfortunately he can do at most K times of swaps. Each time he can only swap two letters. What is the maximum number of the consective same letters?
Assume the string is "bababbaa" and K = 1. By 1 swapping Little Ho can get "aabbbbaa". "bbbb" has length 4 which is also the maximum number of the consective same letters Little Ho can get.
输入
The fist line contains an integer K. (1 <= K <= 100000)
The second line contain a string of lowercase letters. The length is no more than 100000.
输出
Output the answer.
样例输入
1
bababbaa
样例输出
4
题意分析:
1.题是什么?
给你一个十万长度的小写字母字符串,问你在做出最多k次交换操作之后,得到的字符串中最长连续相同字符的最大长度为长.
2.思路
最长连续相同字符只有26种可能,要不是a要不是b要不是c....分别以abc..做目标求一下能在k次交换内得到的最长长度,其中最大的即是答案.
以在bababbaa中找a在k次交换下能得到的最长长度为例,其实就是要找某一子串[l,r)满足下面两个条件:
(1).其中不是a的字母的总数x小于等于k
(这样才可能在最多k次交换之后[l,r)内全是a,动态更新一个nowk记录当前[l,r)内不是a的字母的总数,以1复杂度完成判定)
(2).剩余串[0,l)与[r,n)中的a的个数大于等于x
(就算你交换次数足够,没那么多a给你换有什么用.预处理一个count数组记录每种字符有多少个就能以1复杂度完成判定)
不断的找符合上面两个条件的子串,找到一个就更新一下ans,保留最大的.找完26种字母即为答案.
找子串这一步可以用我的方法,设立左右点l,r,条件递推,可以在近乎n复杂度下找完a下的所有子串,故而总复杂度26*n,搞定.
3.ac代码
#include <stdio.h>
typedef long long ll;
const int maxn=100005;
char s[maxn];
int count[26];
void solve(){
int k;
scanf("%d%s",&k,&s);
for(int i=0;i<26;i++) count[i]=0;
for(int i=0;s[i];i++) count[s[i]-'a']++;
int ans=0;
for(int i=0;i<26;i++){
char cmpchar='a'+i;
int l=0,r=0;
int tempans=0,nowk=0;
while(s[r]){
while(nowk<=k&&nowk<count[i]-(r-l-nowk)&&s[r]){
if(s[r]!=cmpchar){
if(nowk<k&&nowk<count[i]-(r-l-nowk)) nowk++;
else break;
}
r++;
}
if(tempans<r-l) tempans=r-l;
while(s[l]){
if(s[l]!=cmpchar){
l++;
nowk--;
break;
}
l++;
}
}
if(ans<tempans) ans=tempans;
}
printf("%d\n",ans);
}
int main(){
solve();
return 0;
}