zoukankan      html  css  js  c++  java
  • Hard Process(二分)

    Hard Process
    Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

    Description

    You are given an array a with n elements. Each element of a is either 0 or 1.

    Let's denote the length of the longest subsegment of consecutive elements in a, consisting of only numbers one, as f(a). You can change no more than k zeroes to ones to maximize f(a).

    Input

    The first line contains two integers n and k (1 ≤ n ≤ 3·105, 0 ≤ k ≤ n) — the number of elements in a and the parameter k.

    The second line contains n integers ai (0 ≤ ai ≤ 1) — the elements of a.

    Output

    On the first line print a non-negative integer z — the maximal value of f(a) after no more than k changes of zeroes to ones.

    On the second line print n integers aj — the elements of the array a after the changes.

    If there are multiple answers, you can print any one of them.

    Sample Input

    Input
    7 1 1 0 0 1 1 0 1
    Output
    4 1 0 0 1 1 1 1
    Input
    10 2 1 0 0 1 0 1 0 1 0 1
    Output
    5 1 0 0 1 1 1 1 1 0 1
    题解:让改变k个数,使序列连续1的个数最大,我们可以求0的前缀和,然后通过二分来找位置;我竟然用暴力超时了好长时间。。。
    二分:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    #define mem(x,y) memset(x,y,sizeof(x))
    const int MAXN = 300010;
    int num[MAXN];
    int a[MAXN];
    int L, n, k;
    
    int js(int x){
        for(int i = 0; i + x <= n; i++){
            if(num[i + x] - num[i] <= k){
                L = i + 1;
                return true;
            }
        }
        return false;
    }
    int erfen(int l, int r){
        int mid, ans;
        while(l <= r){
            mid = (l + r) >> 1;
            if(js(mid)){
                ans = mid;
                l = mid + 1;
            }
            else 
                r = mid - 1;
        }
        return ans;
    }
    int main(){
        while(~scanf("%d%d",&n, &k)){
            int temp;
            memset(num, 0, sizeof(num));
            for(int i = 1; i <= n; i++){
                scanf("%d", a + i);
                num[i] = num[i - 1] + (a[i] == 0);
            }
            int ans = erfen(0,n);
            for(int i = L; i < L + ans; i++){
                a[i] = 1;
            }
            printf("%d
    ", ans);
            for(int i = 1; i <= n; i++){
                if(i != 1)printf(" ");
                printf("%d",a[i]);
            }puts("");
        }
        return 0;
    }

    暴力超时:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    #define mem(x,y) memset(x,y,sizeof(x))
    const int MAXN = 1000100;
    int num[MAXN];
    int pos[MAXN];
    int p[MAXN];
    int main(){
        int n, k;
        while(~scanf("%d%d",&n, &k)){
            int gg = 0;
            for(int i = 0; i < n; i++){
                scanf("%d", num + i);
                if(num[i] == 1)gg = 1;
            }
            if(!gg){
                printf("%d
    ",k);
                for(int i = 0; i < k; i++){
                    if(i)printf(" ");
                    printf("1");
                }
                for(int i = k; i < n; i++){
                    if(i)printf(" ");
                    printf("0");
                }puts("");
                continue;
            }
            int kg = 0, ans = 0, temp = 0, cnt = 0, tp = 0;
            for(int i = 0; i < n; i++){
                if(kg == 0 && num[i] == 1){
                        temp = 0;
                        kg = 1;
                        cnt = 0;
                        for(int j = i; j < n; j++){
                            
                            if(num[j] == 1){
                                temp++;
                            }
                            else{
                                if(cnt + 1 > k)break;
                                pos[cnt++] = j;
                                temp++;
                            }
                        }
                            int j = i;
                            while(cnt < k && j > 0){
                                pos[cnt++] = --j;
                                temp++;
                            }
                            
                        if(ans < temp){
                            ans = temp;
                            tp = cnt;
                            for(int j = 0; j < tp; j++){
                                p[j] = pos[j];
                            }
                        }
                    }
                if(num[i] == 0)kg = 0;
            }
            for(int i = 0; i < tp; i++){
            //    printf("%d ",p[i]);
                num[p[i]] = 1;
            }//puts("");
            printf("%d
    ", ans);
            for(int i = 0; i < n; i++){
                if(i)printf(" ");
                printf("%d",num[i]);
            }
            puts("");
        }
        return 0;
    }
  • 相关阅读:
    poj 3068 Bridge Across Islands
    XidianOJ 1086 Flappy v8
    XidianOJ 1036 分配宝藏
    XidianOJ 1090 爬树的V8
    XidianOJ 1088 AK后的V8
    XidianOJ 1062 Black King Bar
    XidianOJ 1091 看Dota视频的V8
    XidianOJ 1098 突击数论前的xry111
    XidianOJ 1019 自然数的秘密
    XidianOJ 1109 Too Naive
  • 原文地址:https://www.cnblogs.com/handsomecui/p/5382825.html
Copyright © 2011-2022 走看看