题目
思路
用vector记录0 1 位置,然后分两种情况 只修改1 或只修改0
修改1:
用需要修改的最后一个1的下一个1的位置 减去 需要修改的第一个1的上一个1的位置
即最后一个的下一个 减 第一个的上一个,因为如果字符串第一个字符是1,他就没有上一个1了 所以把他单独拿出来
然后获得的连续字串的长度与上一次获得的比较,取最大的
修改0与1相同 最后比较取最大值
详细注解见代码
AC代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
vector<int>l,y;
char a[200007];
int main()
{
int n,k;
cin>>n>>k;
getchar();
for(int i=1;i<=n;i++)
{
scanf("%c",&a[i]);
if(a[i]=='0')l.push_back(i);
else y.push_back(i);
} ///记录 0 1 的位置
l.push_back(n+1);
y.push_back(n+1);///把n+1放进去是为了在后面算距离的时候不出错
///比如 n=5 字符串为01011 记录的0的位置有 1 3 把n+1放进去后,集合里有 1 3 6
///这时算第一个零和第二个零之间有几个1(两个0之间的距离) 那么就是 3-1-1
///算第2个0后面有几个0 那么就是 6-3-1
///因为第2个0后面没有0了 所以把n+1放进去就可以计算距离了
if(l.size()-1==n||y.size()-1==n||l.size()-1<=k||y.size()-1<=k){cout<<n<<endl;return 0;}
///如果字符串都为1或都为0 或1的个数<k 或 0的个数<k 直接输出字符串长度n
///多了一个n+1 所以长度要减1
int mmy=0,mml=0;
for(int i=0;i<=y.size()-k-1;i++)///因为vector集合里的数 下标是从0开始的,所以从0开始遍历(存进去的是每个数的位置,位置是从1开始编号的)
{
if(i==0)///字符串第一个字符是1
{
mmy=y[i+k]-1;/// 假若k=2 那么就是把 y[0] y[1] 位置的改成0 那么此时连续的0的长度就是y[2]-1;
///即 用需要修改的最后一个1(y[1])的下一个1的位置(y[2])减1;
}
else
{
mmy=max(mmy,y[i+k]-y[i-1]-1);///y[i+k]-y[i-1]-1,是 用需要修改的最后一个1的下一个1的位置 减去 需要修改的第一个1的上一个1的位置
///(最后一个的下一个 减 第一个的上一个)因为如果字符串第一个字符是1,他就没有上一个1了 所以才单独把if(i==0)拿出来
///然后获得的连续字串的长度与上一次获得的比较,取最大的
}
}
//cout<<endl;
///下面是只修改0 分析与上面修改1 相同
for(int i=0;i<=l.size()-k-1;i++)
{
if(i==0)
{
mml=l[i+k]-1;
}
else
{
mml=max(mml,l[i+k]-l[i-1]-1);
//cout<<mml<<endl;
}
}
cout<<max(mml,mmy)<<endl;///比较字符串只修改1和只修改0能获得的最大连续子串哪一个更大
return 0;
}