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
7 1 1 0 0 1 1 0 1
4 1 0 0 1 1 1 1
10 2 1 0 0 1 0 1 0 1 0 1
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; }