链接:https://ac.nowcoder.com/acm/contest/893/F
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
你有一个长度为 n 的 01 串S,你可以执行最多 m 次操作。
对于每次操作,你可以选择一个位置 i 满足 $1 \le i \le n$,翻转这一位的值,0变成1,1变成0。
定义一个 01 串的价值为其中最长连续0的个数和最长连续1的个数的较大值,求S在经过最多m次操作后的最大价值。
输入描述:
* 第一行一个整数 T ,表示接下来有 T 个样例。 * 首先输入n,m,表示S串的长度n和操作次数m,其中,; * 接下来输入一个长度为n的字符串S。
输出描述:
一个整数,表示题面上描述的最大价值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char s[100005];
struct node{
int l,r;
}a[100005],b[100005];
int n,m,M;
int ta,tb;
int solve(node a[],int ta){
m=M;
int ans=a[1].r-a[1].l+1+m;
int l=1;
for(int r=2;r<=ta;r++){
m-=a[r].l-a[r-1].r-1;
while(m<0&&l<r){
m+=a[l+1].l-a[l].r-1;
l++;
}
ans=max(ans,a[r].r-a[l].l+1+m);
}
return min(ans,n);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
scanf("%s",s+1);
M=m;
ta=0,tb=0;
int l=0,r=0;
for(int i=1;i<=n;i++){
if(s[i]=='0'&&l==0){
l=i;
r=i;
}
else if(s[i]=='0'&&l!=0){
r=i;
}
if(s[i]!='0'&&l!=0){
++ta;
a[ta].l=l;
a[ta].r=r;
l=0,r=0;
}
}
if(l!=0){
++ta;
a[ta].l=l;
a[ta].r=r;
l=0,r=0;
}
if(ta==0){
printf("%d\n",n);
continue;
}
l=0,r=0;
for(int i=1;i<=n;i++){
if(s[i]=='1'&&l==0){
l=i;
r=i;
}
else if(s[i]=='1'&&l!=0){
r=i;
}
if(s[i]!='1'&&l!=0){
++tb;
b[tb].l=l;
b[tb].r=r;
l=0,r=0;
}
}
if(l!=0){
++tb;
b[tb].l=l;
b[tb].r=r;
l=0,r=0;
}
if(tb==0){
printf("%d\n",n);
continue;
}
printf("%d\n",max(solve(a,ta),solve(b,tb)));
}
return 0;
}