【Codeforces 660C-Hard Process】二分/尺取

Hard Process

題目鏈接:

https://codeforces.com/contest/660/problem/C

Description

在這裏插入圖片描述

Input

在這裏插入圖片描述

Output

在這裏插入圖片描述

Sample Input

7 1
1 0 0 1 1 0 1

Sample Output

7 1
1 0 0 1 1 0 1

題意

給你一個長度爲n的01串,最多可以把其中k個0變成1,問操作之後可以得到的最長的連續的1有多長。

題解:

首先考慮改變的k個0一定要是連續的,不然是沒有意義的。
之後就可以採用尺取/二分的方法來解決這道題,這裏講一下二分的做法。
首先我們前綴和處理出到每個點爲止0的個數。
之後枚舉每一個作爲連續的1的起點的情況。
如果到當前點爲止0的個數爲x,那麼到第x+k個0這之間所有的0都可以變成1。
於是我們二分找到第一個0的個數大於等於x+k的位置,再加上當前點之前連續的1和這個位置之後連續的1的個數即可。按照這個方法枚舉每一個位置作爲更改0的起點的結果,取最大值即可。

代碼

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<<x<<endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
typedef long long ll;
const int maxn =3e5+10;
int a[maxn],pre[maxn];
int x[maxn],y[maxn];
int main()
{
    //freopen(".in","r",stdin);
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++) pre[i]=pre[i-1]+(a[i]==0);
    for(int i=1;i<=n;i++)
    {
        if(a[i]==1) x[i]=x[i-1]+1;
        else x[i]=0;
    }
    for(int i=n;i>=1;i--)
    {
        if(a[i]==1) y[i]=y[i+1]+1;
        else y[i]=0;
    }
    int ans=-1,flag=-1;
    for(int i=0;i<=n;i++)
    {
        int pos=lower_bound(pre+1,pre+1+n,pre[i]+k)-pre;
        if(pos==n+1)
        {
            if(x[i]+n-i>ans) flag=i;
            ans=max(ans,x[i]+n-i);
        }
        else if(pre[pos]==pre[i]+k)
        {
            if(x[i]+pos-i+y[pos+1]>ans) flag=i;
            ans=max(ans,x[i]+pos-i+y[pos+1]);
        }
    }
    if(flag==-1)
    {
        printf("0\n");
        for(int i=1;i<=n;i++) printf("%d ",a[i]);
    }
    else
    {
        printf("%d\n",ans);
        for(int i=1;i<=flag;i++) printf("%d ",a[i]);
        for(int i=flag+1;i<=n;i++)
        {
            if(a[i]==1) printf("%d ",a[i]);
            else
            {
                if(k>0)
                {
                    k--;
                    printf("1 ");
                }
                else printf("0 ");
            }
        }
    }

    return 0;
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章