題意:
有K次機會能將0變爲1,問一個01串最長能有多少個連續的1?
思路:
剛開始一直確定不下來解題思路,又想dp,又想區間二分,但都不是很清晰。n的取值範圍決定了算法時間複雜度最多O(nlgn),二分連續串開始的位置,但是需要有一個輔助數組來表示到i的1的數目。
代碼實現:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_N = 300010;
int N,K;
int res;
int sta,en;
int num[MAX_N];
int sum[MAX_N];
int check(int pos,int cur);
int main()
{
while( scanf("%d%d",&N,&K) != EOF ){
res = 0;
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
for( int i = 1; i <= N; i++ ){
scanf("%d",&num[i]);
sum[i] = sum[i-1]+num[i];
}
for( int i = 1; i <= N; i++ ){
int left = -1;
int right = i;
int mid;
while( right-left > 1 ){
mid = (left+right)/2;
if( check(mid,i) == 1 ){
right = mid;
}
else{
left = mid;
}
}
if( i-right > res ){
res = i-right;
sta = right;
en = i;
}
}
printf("%d\n",res);
for( int i = 1; i <= N; i++ ){
if( i> sta && i<= en ){
printf("1");
}
else{
printf("%d",num[i]);
}
if( i != N ){
printf(" ");
}
else{
printf("\n");
}
}
}
return 0;
}
int check(int pos,int cur){
int dis = cur-pos;
int tmp = sum[cur]-sum[pos];
if( tmp+K < dis ){
return 0;
}
else{
return 1;
}
}