Description
you are given a 01 sequence whose size is n. you can change at most k 0 into 1 in the sequence. now I want to know how many consecutive 1 in the sequce at most after you do the change.Input
The first of input is an integer t which stands for the number of test cases. for each test case, the first line contains two number n, k ( 1 <= n <= 100000, 0 <= k <= n ). the next contains n element of the sequence, whose value is 0 or 1.Output
output the answer in one line for each test case.Sample Input
2 4 2 1 0 0 1 4 1 1 0 1 0Sample Output
4 3Source
baihacker&onmylove@scuacm Sichuan University Programming Contest 2012 Preliminary
//分析:其中i-j中0的个数可以表达如下:j-i+1-(sum[j]-sum[i-1]);其中sum[i]表示前i个数之和。
分析表达式知假如i是确定的,那么j-i+1和sum[j]-sum[i-1]都是随着j而递增的,所以我们可以从i=1...n,每次遍历i为起点,要找到一个最大的j使得它和i之间的0的个数不大于k,由于之前的表达式是递增的所以可以每次二分出一个j,最后取最优,时间复杂度为O(n*logn);
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define maxn 100005 struct NODE { int ti,num; }node[maxn]; int a[maxn]; int main() { int t,n,k; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&k); int i,j; memset(node,0,sizeof(node)); for(i=1;i<=n;i++) { scanf("%d",&a[i]); node[i].ti=i; node[i].num+=node[i-1].num+a[i]; } int tmp=0,best=0,flag=0; for(i=1;i<=n;i++) { int lif=i,rig=n,mid=(lif+rig)>>1; flag=0; while(lif<=rig) { if((node[mid].ti-node[i].ti+1-(node[mid].num-node[i-1].num)>k)) rig=mid-1; else lif=mid+1; mid=(lif+rig)>>1; } if(mid-i+1>best) best=mid-i+1; } printf("%d\n",best); } return 0; }
baihacker&onmylove@scuacm
Sichuan University Programming Contest 2012 Preliminary
804

被折叠的 条评论
为什么被折叠?



