版权声明:请大家斧正,如喜欢的话,为拙见点一个赞吧。 https://blog.csdn.net/qq_39897867/article/details/86728609
题目
Description
给出包含一个N个整数的数组A。找出一段长度至少为K的连续序列,最大化它的平均值。
请注意:一段子序列的平均值是子序列中所有数的和除以它的长度。
Input
第一行包含两个整数N(1<=N<=300000),K(1<=K<=N)。
第二行包含N个整数,代表数组A,1<=ai<=10^6。
Output
一行一个实数,代表最大的平均值。允许在0.001以内的绝对误差。
结题思路
根据wyc大佬的原话:题目给出了spj,显然二分答案。
然后应该怎么判断呢?我们可以将所有a[i]-=mid,若一段长度>=k的区间和,则答案合法。
前缀和优化。
代码
#include<cstdio>
#include<algorithm>
#define db double
#define rr register
#define fre(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
using namespace std;
const int maxn=300005;
const db e=1e-7;
int n,k,a[maxn]; db b[maxn],ans,l=0,r,mid;
inline bool check(db x){
db c=-2147483647.0*2147483647;
for(rr int i=1;i<=n;i++) b[i]=b[i-1]+(db)(a[i]-x);
for(rr int i=n-k+1;i>=1;i--) if ((c=max(c,b[i+k-1]))-b[i-1]>=0) return 1;
return 0;
}
int main(){
// fre(average);
scanf("%d%d",&n,&k); r=1000000;
for(rr int i=1;i<=n;i++) scanf("%d",&a[i]);
while (r-l>e) if (check((mid=(l+r)/2))) ans=mid,l=mid; else r=mid;
return 0&printf("%.6lf",ans);
}