题意:给你一个数组,其中有n个元素。每个元素不是0就是1。 现在可以进行k次操作,每次操作可以改变数组中的一个元素(只能改成0或1)。 请你求出操作后最长连续1的序列的长度,并输出操作后的序列。
题解 :
滑动窗口/尺取法
容易想到,枚举左右端点,然后判断里面0的个数是是否大于k。
对于右端点,如果是0,可以延伸(不超过k)。只需要枚举左端点。
维护一个窗口,对于这个区间,0的个数不够的时候延伸右端点,一旦超过,就右移左端点直到满足条件。
【这样能保证对于第二种解法枚举的左端点没有必要进行单独的枚举,这样子每次对于左端点都是所能达到的最长距离】
记录中间的最佳结果即可。
#include<bits/stdc++.h>
using namespace std;
/*唯有全力以赴*/
int L,R;
int ans;
int temp;
int A[300010];
int main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)scanf("%d",&A[i]);
int s=1,t=1;
temp = (A[1]==0 ? 1 : 0);
while(s<=n&t<=n)
{
if(temp<=k&&t-s+1>ans)
{
L=s,R=t,ans=R-L+1;
}
if(temp<=k)
{
t++;
if(A[t]==0)temp++;
}
else
{
if(A[s]==0)temp--;
s++;
}
//cout<<s<<" "<<t<<endl;
}
//cout<<L<<" "<<R<<endl;
for(int i=L;i<=R;i++)
{
A[i]=1;
}
cout<<ans<<endl;
for(int i=1;i<=n;i++)
{
cout<<A[i]<<" ";
}
//system("pause");
}