https://ac.nowcoder.com/acm/contest/893/F?&headNav=acm

题目链接在上

题意:给一串n位长度的0,1字符串,允许最多m次修改,即0改成1,1改成0,问:最终最长的连续相同的字符串可以是多少长度?

样例解读:
5 1
00101
长度为5,修改1次,即把1改成0,变成00001,答案是4
2 1
01
长度为2,修改1次,这就随便了,1改成0,或者0改成1,变成00,或11,答案是2

思路:
要求最长,换个思路:告诉你有一段连续相同的字符串长度为x,能否在m次修改里,判断成功与否?
可以。前缀和+for循环判断
题意再转换:最长 即 x 最大
二分。

前缀和:zero[ed] - zero[st - 1]表示 从[st, ed] 区间共有多少 0
二分:标准框架

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 20;
int zero[maxn];
int one[maxn];
char s[maxn];
    int T, n, m;

int calc(int x){
    for(int st = 1; st + x - 1 <= n; st ++){
        int ed = st + x - 1;
        if (zero[ed] - zero[st - 1] <= m) return 1;
        if (one[ed] - one[st - 1] <= m) return 1;
    }
    return 0;
}

int main(){
    //freopen("input.txt", "r", stdin);
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &m);
        scanf("%s", s + 1);
        //printf("%s\n", s + 1);
        memset(zero, 0, sizeof(zero));
        memset(one, 0, sizeof(one));
        for(int i = 1; i <= n; i++)
            if (s[i] == '0'){
                zero[i] = zero[i - 1] + 1;
                one[i] = one[i - 1];
            }
            else{
                one[i] = one[i - 1] + 1;
                zero[i] = zero[i - 1];
            }
        //for(int i = 1; i <= n; i++)
        //    printf("%d%c", zero[i], i==n ? '\n' : ' ');
        //for(int i = 1; i <= n; i++)
        //    printf("%d%c", one[i], i==n ? '\n' : ' ');
        int l = 0;
        int r = n;
        int mid, ans;
        while(l <= r){
            mid = (l + r) >> 1;
            if (calc(mid)){
                l = mid + 1;
                ans = mid;
            }
            else r = mid - 1;
        }
        printf("%d\n", ans);
    }
    return 0;
}