很好的一个二分法的题。
首先用一个sum数组储存到当前节点0的个数,然后用一个 for 循环从第一个数(不包括)开始尺取,依次更新结果就行了。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int num[300000+11];
int sum[300000+11] = {0}; //在当前节点0的个数
int main()
{
int n,k;
int pos;
int l,st,endd; //长度,起点,终点(闭区间)
while (~scanf ("%d %d",&n,&k))
{
memset (sum,0,sizeof (sum));
for (int i = 0 ; i < n ; i++)
{
scanf ("%d",&num[i]);
if (num[i])
sum[i] = sum[i-1];
else
sum[i] = sum[i-1] + 1;
}
//首先先计算从第一个数开始的结果
pos = upper_bound (sum , sum + n , k) - 1 - sum;
l = pos + 1;
st = 0;
endd = pos;
//然后计算左开右闭区间的最优解
for (int i = 0 ; i < n ; i++)
{
pos = upper_bound (sum , sum + n , sum[i] + k) - 1 - sum;
if (pos - i > l)
{
l = pos - i;
st = i + 1;
endd = pos;
}
}
//最后输出
for (int i = st ; i <= endd ; i++)
num[i] = 1;
printf ("%d\n",l);
for (int i = 0 ; i < n ; i++)
printf ("%d ",num[i]);
printf ("\n");
}
return 0;
}