CF660C C - Hard Process

题意:给你一个数组,其中有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");
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值