Codeforces 660C Hard Process【二分 Or 尺取】

题目链接:

http://codeforces.com/problemset/problem/660/C

题意:

给定0.1组成的数组,可以改变k个0使其为1,问最终可以得到的连续的1的最大长度。

分析:

很容易想到二分答案的做法,
二分长度,然后找是否存在满足题意的区间。
还可以用尺取法,这样在O(n)时间负责度内就可以完成,但是个人感觉写起来没有二分直观。。

代码:

二分:

#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
const int maxn = 300000 + 5;
int a[maxn];
int t[maxn];
int n, k;
int f1 = -1;
bool judge(int p)
{
    for(int i = 0; i + p - 1< n; i++){
            if(t[i + p - 1] - t[i - 1] + k >= p) {
                f1 = i;
                 return true;
            }
    }
    return false;
}
int main (void)
{
   scanf("%d%d", &n, &k);
   for(int i = 0; i < n; i++){
        scanf("%d", &a[i]);
        t[i] = t[i - 1] + (a[i] == 1);
   }
   int l = 0, r = n + 1;
   while(l < r - 1){
      int mid = (l + r) / 2;
      if(judge(mid)) l = mid;
      else r = mid;
   }
   printf("%d
", l);
   for(int i = 0; i < f1; i++){
     printf("%d ", a[i]);
   }
   for(int i = f1; i < f1 + l; i++)
       printf("1 ");
    for(int i = max(f1 + l, 0); i < n; i++){
        printf("%d ", a[i]);
    }
    return 0;

}

尺取法:(two pointers)

#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
const int maxn = 300000 + 5;
int a[maxn], t[maxn];
int n, k;
int main (void)
{
   scanf("%d%d", &n, &k);
   for(int i = 0; i < n; i++){
        scanf("%d", &a[i]);
   }
    int r = 0, cnt = 1, ans = 0, MAX = 0;
    int f1 = -1, f2 = -1;
    for(int i = 0; i < n; i++){
        if(a[i - 1] == 0){
            cnt--;
            while(cnt <= k && r < n){
                    if(a[r] == 1){
                        r++;
                    }else{
                        if(cnt == k) {break;}
                        cnt++;
                        r++;
                    }
            }
        ans = r - i ;
        }else  ans--;
        if(ans > MAX){
            MAX = ans;
            f1 = i;
            f2 = r - 1;
        }
    }
    cout<<MAX<<endl;
    if(k == 0){
        for(int i = 0; i < n; i++) cout<<a[i]<<' ';
        return 0;
    }
    for(int i = 0; i < f1; i++) cout<<a[i]<<' ';
    for(int i = f1; i <= f2; i++) cout<<1<<' ';
    for(int i = f2 + 1; i < n; i++)  cout<<a[i]<<' ';
    return 0;
}
原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758667.html