链接:https://ac.nowcoder.com/acm/contest/893/F
来源:牛客网
题目描述
你有一个长度为 n 的 01 串S,你可以执行最多 m 次操作。
对于每次操作,你可以选择一个位置 i 满足 1≤i≤n1≤i≤n,翻转这一位的值,0变成1,1变成0。
定义一个 01 串的价值为其中最长连续0的个数和最长连续1的个数的较大值,求S在经过最多m次操作后的最大价值。
输入描述:
* 第一行一个整数 T ,表示接下来有 T 个样例。 * 首先输入n,m,表示S串的长度n和操作次数m,其中1≤n≤1000001≤n≤100000,0≤m≤10000≤m≤1000; * 接下来输入一个长度为n的字符串S。
输出描述:
一个整数,表示题面上描述的最大价值。
示例1
输入
复制
2 5 1 00101 2 1 01
输出
复制
4 2
说明
第一个串翻转第三个位置,00001的价值为4;第二个串翻转第一个位置,11的价值为2。
题解用的二分+前缀和
我用的尺取,感觉挺好写的
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=1e5+5;
char s[maxn];
int main()
{
int t;scanf("%d",&t);
while(t--)
{
queue<int>q1,q2;
int n,m;scanf("%d%d%s",&n,&m,s+1);
int k=0,cnt0=0,cnt1=0;
int l=1,r=1;
while(r<=n) //算0
{
if(s[r]=='1') {q1.push(r);k++;if(k>m){l=q1.front()+1;q1.pop();k--;}}
cnt0=max(cnt0,r-l+1);r++;
}
k=0,l=1,r=1;
while(r<=n) //算1
{
if(s[r]=='0'){q2.push(r);k++;if(k>m){l=q2.front()+1;q2.pop();k--;}}
cnt1=max(cnt1,r-l+1);r++;
}
printf("%d\n",max(cnt0,cnt1));
}
return 0;
}