High school student Vasya got a string of length n as a birthday present. This string consists of letters 'a' and 'b' only. Vasya denotesbeauty of the string as the maximum length of a substring (consecutive subsequence) consisting of equal letters.
Vasya can change no more than k characters of the original string. What is the maximum beauty of the string he can achieve?
The first line of the input contains two integers n and k (1 ≤ n ≤ 100 000, 0 ≤ k ≤ n) — the length of the string and the maximum number of characters to change.
The second line contains the string, consisting of letters 'a' and 'b' only.
Print the only integer — the maximum beauty of the string Vasya can achieve by changing no more than k characters.
4 2 abba
4
8 1 aabaabaa
5
In the first sample, Vasya can obtain both strings "aaaa" and "bbbb".
In the second sample, the optimal answer is obtained with the string "aaaaabaa" or with the string "aabaaaaa".
题目大意:
给你一个长度为n的字符串,字符串中只有a和b两种字符,vasya这个人定义一种美丽字符串,是指这个字符串全是字符a,或者全是字符b。我们有k次修改字符的机会,问给出的串其中最长的连续美丽子串长度为多少。
思路:
1、首先我们预处理conta【i】和contb【i】。分别表示从第一个字符到第i个字符中字符a的数量和字符b的数量。
2、考虑到这个字符串有这样的特性:
①假设某个子串的起点为i,那么向后枚举子串的终点j,起始的时候是能够构成美丽串的,随着终点j的变远,需要修改的字符越来越多,也就变成了不能构成美丽串,根据这个递减的特性,满足二分的条件,所以我们使用二分是可以搞定这个问题的:
②我们枚举最长美丽子串的起点,然后我们二分美丽子串的终点,如果当前枚举到的起点是i,二分当前美丽子串的终点为mid.然后判断从起点i到终点mid中有多少个字符a,有多少个字符b,这里我们之前预处理了,其中字符a的数量就是:ca=conta【mid】-conta【i-1】,字符b的数量就是cb=contb【mid】-contb【i-1】。引用贪心思想:那么我们取ca,cb中小的那个值记做minn,用于作为被修改的字符种类,如果minn<=k,那么当前子串就是一个合法的美丽子串。
③那么一直枚举下去,只要当前子串符合美丽子串的判定,我们维护ans=max(mid-i+1,ans)即可。
Ac代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
char a[1000000];
int conta[1000000];
int contb[1000000];
int n,k;
void init()
{
memset(conta,0,sizeof(conta));
memset(contb,0,sizeof(contb));
for(int i=0;i<n;i++)
{
if(i==0)
{
if(a[i]=='a')conta[i]=1;
else contb[i]=1;
continue;
}
if(a[i]=='a')
{
conta[i]=conta[i-1]+1;
contb[i]=contb[i-1];
}
if(a[i]=='b')
{
conta[i]=conta[i-1];
contb[i]=contb[i-1]+1;
}
}
}
int judge(int start,int end)
{
int ca=conta[end]-conta[start-1];
int cb=contb[end]-contb[start-1];
int minn=min(ca,cb);
if(minn<=k)return 1;
else return 0;
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
scanf("%s",a);
init();
int ans=0;
for(int i=0;i<n;i++)
{
int mid;
int l=i;
int r=n-1;
while(r>=l)
{
mid=(l+r)/2;
if(judge(i,mid)==1)
{
ans=max(ans,mid-i+1);
l=mid+1;
}
else
{
r=mid-1;
}
}
}
printf("%d\n",ans);
}
}