题目描述:
nozomi看到eli在字符串的“花园”里迷路了,决定也去研究字符串问题。
她想到了这样一个问题:
对于一个 “01” 串而言,每次操作可以把 0 字符改为 1 字符,或者把 1 字符改为 0 字符。所谓 “01” 串,即只含字符 0和字符 1 的字符串。
nozomi有最多 K 次操作的机会。她想在操作之后找出一个尽可能长的连续子串,这个子串上的所有字符都相同。
nozomi想问问聪明的你,这个子串的长度最大值是多少?
注: K 次操作机会可以不全部用完。
如果想知道连续子串的说明,可以去问问eli,nozomi不想再讲一遍。
输入描述:
第一行输入两个正整数 n 和 k
( 1 <= k <= n <= 200000)
输入仅有一行,为一个长度为 n 的、仅由字符 0 和 1 组成的字符串。
输出描述:
一个正整数,为满足条件的子串长度最大值。
分析:
此次使用尺取法解决,通过题目分析,可知存在两种情况,一、将字符 0 转换为字符 1,二、将字符1 转换为字符0,分两种情况讨论,取其中两种情况中最大值。在对每种情况讨论时,可以定义两个指针l 和r,分别指向区间的左端和右端,通过对指针的移动得到最长的连续字串
代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN = 200005;
string str;
int ans;
int n,k;
int Handle(char a,char b) //Handle函数表示将 a字符 变为 b字符
{
//l r 充当遍历字符串str的左右指针
//change表示已经使用了多少次操作
int res=1,l=0,r=0,change=0;
for(int i=0;i<n;++i)
{
if(str[i] == a)
{
if(change < k) //表示操作机会未用完
{
++r;
++change;
}
else
{
//此操作保证l和r包围的区间内的a的总数保持不变 此区间中最多只包含k个字符a
while(l <= r && str[l] != a)
l++;
++l;
++r;
}
}
else
++r;
res = max(res,r-l);
}
return res;
}
int main()
{
scanf("%d%d",&n,&k);
cin >> str;
ans = max(Handle('0','1'),Handle('1','0'));
printf("%d\n",ans);
return 0;
}