题目描述
你有一个长度为 n 的 01 串S,你可以执行最多 m 次操作。
对于每次操作,你可以选择一个位置 i 满足 1≤i≤n,翻转这一位的值,0变成1,1变成0。
定义一个 01 串的价值为其中最长连续0的个数和最长连续1的个数的较大值,求S在经过最多m次操作后的最大价值。
输入
第一行一个整数 T ,表示接下来有 T 个样例。
首先输入n,m,表示S串的长度n和操作次数m,其中1≤n≤100000,0≤m≤1000;
接下来输入一个长度为n的字符串S。
输出
一个整数,表示题面上描述的最大价值。
样例输入
复制样例数据
2
5 1
00101
2 1
01
样例输出
4
2
提示
第一个串翻转第三个位置,00001的价值为4;第二个串翻转第一个位置,11的价值为2。
思想:尺取,区间问题简单的可不可以先想一下尺取
这里就是让r++,cnt记录1的个数,直到当cnt的个数超过m个时,开始对l进行操作,让cnt–,意思是不反转他,直到r>n时停止,用num来记录最长的区间长度,最后返回就行了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stdlib.h>
#include <cstring>
typedef long long ll;
using namespace std;
string s;
int n,m;
int t;
int solve1(){
int l=0,r=0,cnt=0,num=0;
while(r<n){
if(s[r]=='1')
cnt++;
while(cnt>m){
if(s[l]=='1')
cnt--;
l++;
}
num=max(num,r-l+1);
r++;
}
return num;
}
int solve0(){
int l=0,r=0,cnt=0,num=0;
while(r<n){
if(s[r]=='0')
cnt++;
while(cnt>m){
if(s[l]=='0')
cnt--;
l++;
}
num=max(num,r-l+1);
r++;
}
return num;
}
int main(){
cin>>t;
while(t--){
cin>>n>>m;
cin>>s;
int ans=max(solve0(),solve1());
cout<<ans<<endl;
}
return 0;
}