您的位置:首页 > 其它

【NOIP模拟】平均数

2016-06-26 07:53 204 查看

Description

给出包含一个N个整数的数组A。找出一段长度至少为K的连续序列,最大化它的平均值。

请注意:一段子序列的平均值是子序列中所有数的和除以它的长度。

Solution

一看到求什么最大最小值什么的就要想到用二分答案。

然后是平均数,要求他要大于某个数,那么我们就把这些数同时减去这个平均数,最后如果满足长度大于m的子串和不小于0就成立。

那么我们怎样保证长度大于m

我们循环从m到n循环,然后用1到i的和减去最小的前缀和。

然后就可以O(n)搞定这一结果。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
typedef double db;
using namespace std;
const int maxn=300007;
int i,j,k,t,n,m;
db ans,l,r,mid,f[maxn],a[maxn],b[maxn];
bool pan(int x){
int i,l=0,p=-0x7fffffff;
db k=0,j=0;
fo(i,m,n){
if(b[i]-k>=0)return 1;
if(b[i-m+1]<k)k=b[i-m+1];
}
return 0;
}
int main(){
freopen("average.in","r",stdin);
freopen("average.out","w",stdout);
scanf("%d%d",&n,&m);
fo(i,1,n){
scanf("%lf",&a[i]);
r+=a[i];
}
while(r-l>1e-5){
mid=(l+r)/2;b[0]=0;
fo(i,1,n)a[i]-=mid,b[i]=b[i-1]+a[i];
if(pan(mid))l=mid;else r=mid;
fo(i,1,n)a[i]+=mid;
}
printf("%.5lf\n",l);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: