自己思路:
2种情况:把0换成1 或者 把1换成0
难点:不知道起始位置
大佬思路
一,尺取法
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
string s;
int n, k;
int deal(char a, char a1) //把a变成a1
{
int L = 0, R = 0, change = 0, ans = 1;
for (int i = 0; i < n; i++){
if (s[i] == a){
if (change < k){
change++;
R++;
}
else{
while (L <= R && s[L] != a) L++;
L++;
R++;
}
}
else R++;
ans = max(ans, R - L );
}
return ans;
}
int main(){
while (cin >> n >> k){
cin >> s;
cout << max(deal('1', '0'), deal('0', '1')) << endl;
}
}
二,贪心算法
作者:神崎兰子
链接
来源:牛客网
显然操作要么全1变0,要么全0变1。
分别处理两种操作即可。对于1变0的情况,可以分别统计每个1的前缀1和后缀1的位置(第一个1的前缀为 000 ,最后一个1的后缀为 n+1n+1n+1 ),那么 kkk 次操作,即变换连续 kkk 个1,最终的字符串长度就是第 iii 个1的前缀1到第i+ki+ki+k个后缀1之间的距离。
对于0变1的情况同理。
#include<bits/stdc++.h>
using namespace std;
string s;
vector<int>v0,v1; //v0存字符'0'的坐标位置,v1存字符'1'的坐标位置
int main(){
int n,k,i,j;
cin>>n>>k;
cin>>s;
v0.push_back(-1);
v1.push_back(-1);
for(i=0;i<n;i++){
if(s[i]=='0')v0.push_back(i);
else v1.push_back(i);
}
v0.push_back(n);
v1.push_back(n);
int ma=0;
if(v0.size()-2<=k)ma=n;
else{
for(i=1,j=k;j<v0.size()-1;i++,j++){
ma=max(ma,v0[j+1]-v0[i-1]-1);
}
}
if(v1.size()-2<=k)ma=n;
else{
for(i=1,j=k;j<v1.size()-1;i++,j++){
ma=max(ma,v1[j+1]-v1[i-1]-1);
}
}
cout<<ma;
}