Link
求,一段长度不小于k的连续子段最大的平均值.
二分平均值(注意是小数),然后处理一下前缀和,再选长度>=m的区间,存下它比平均值*x多多少,然后二分。
输出平均值
#include<cstdio>
#include<iostream>
using namespace std;
int n,m;
double a[100001],l,r,mid,sum[100001],minn,anss;
int main(){
l=1e20;r=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){ //读入
scanf("%lf",&a[i]);
l=min(l,a[i]);
r=max(r,a[i]);
}
while(r-l>1e-5){ //1e-5=1*10^(-5)=0.00001
mid=(l+r)/2.0;
sum[1]=a[1]-mid;
for(int i=2;i<=n;++i)
sum[i]=sum[i-1]+a[i]-mid; //前缀和,这里直接减去了mid
minn=1e20;anss=-1e20;
for(int i=m;i<=n;++i){ //寻找区间,从m开始,保证至少区间有m个数
minn=min(minn,sum[i-m]); //区间前保证是最小值,那么区间内的就是最大值
anss=max(anss,sum[i]-minn); //存一下
}
if(anss>=0) l=mid; //判断
else r=mid;
}
cout<<int(r*1000)<<endl; //输出
}
(有参考)-