F尺取法
题目的意思是给定一个长度为n的01字符串,可以翻转m次,求最长的连续0或者1的序列。
分析:这里就是求一段区间[l,r]内连续长度最长,可以本能地想到尺取法,暴力遍历这个01字符串即可。
#include<iostream>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int T,n,m;
int ans=0,ans1=inf;
string s;
int main(){
std::ios::sync_with_stdio(false);
cin>>T;
while(T--){
cin>>n>>m;
cin>>s;
int l,r,cnt,num;
l=r=cnt=num=0;
ans=0;
ans1=inf;
//计算0连续的最大个数
while(r<n){
//先尽可能向右移动右端点
while((r<n&&cnt<m)||s[r]=='0'){
if(s[r]=='0'){
num++;
r++;
}
else if(s[r]=='1'&&cnt<m){
num++;
r++;
cnt++;
}
ans=max(ans,num);
}
//r无法再移动了,再开始移动左端点
if(s[l]=='0'){
l++;
num--;
}
else{
l++;
num--;
cnt--;
}
ans=max(ans,num);
}
//计算1连续的最大个数
l=r=cnt=num=0;
while(r<n){
//先尽可能向右移动右端点
while((r<n&&cnt<m)||s[r]=='1'){
if(s[r]=='1'){
num++;
r++;
}
else if(s[r]=='0'&&cnt<m){
num++;
r++;
cnt++;
}
ans=max(ans,num);
}
//r无法再移动了,再开始移动左端点
if(s[l]=='1'){
l++;
num--;
}
else{
l++;
num--;
cnt--;
}
ans=max(ans,num);
}
cout<<ans<<endl;
}
return 0;
}