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;
}



京公网安备 11010502036488号