一个正整数数列 A 求一个平均数最大的长度不小于L 的子段。
二分平均数,将原数列A每一项减去mid。有大于0的字段则移左端点,否则移动右端点。
#include<bits/stdc++.h>
using namespace std;
const double esp=1e-5;
const int MAXN=1000000;
int n,L;
double a[MAXN],pre[MAXN],b[MAXN];
int main()
{
cin>>n>>L;
for(int i=1;i<=n;i++) scanf("%lf",&a[i]);
double l=1e-6,r=1e6;
pre[0]=0;
while(r-l>esp)
{
double mid=(l+r)/2;
for(int i=1;i<=n;i++) b[i]=a[i]-mid,pre[i]=pre[i-1]+b[i];
double ans=-1e10,minn=1e10;
for(int i=L;i<=n;i++)
{
minn=min(minn,pre[i-L]);
ans=max(ans,pre[i]-minn);
}
if(ans>=0) l=mid; else r=mid;
}
cout<<int(r*1000)<<endl;
return 0;
}