bzoj 5090: 组题

来源:互联网 发布:知乎删除问题 编辑:程序博客网 时间:2024/06/01 10:05

题意:

问至少连续k个数最大平均值是多少。

题解:

分数规划裸题。
二分下答案,将每个数减去答案,就是看否有一段和大于0。
那么前缀和就好了。
code:

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#define LL long longusing namespace std;const int inf=1e8;const double eps=1e-7;int n,k,a[100010];LL Sum[100010];double sum[100010];LL AA,BB;int gcd(LL a,LL b){    if(a==0) return b;    return gcd(b%a,a);}bool check(double x){    sum[0]=0.0;    for(int i=1;i<=n;i++)        sum[i]=sum[i-1]+(double)a[i]-x;    double mi=0;int p=0;    for(int i=k;i<=n;i++)    {        if(sum[i]-mi>=0)        {            AA=Sum[i]-Sum[p];BB=(LL)(i-p);            return true;        }        if(sum[i-k+1]<mi) mi=sum[i-k+1],p=i-k+1;    }    return false;}int main(){    scanf("%d %d",&n,&k);    double l=-100000000.0,r=100000000.0;    for(int i=1;i<=n;i++)    {        scanf("%d",&a[i]);Sum[i]=Sum[i-1]+(LL)a[i];        l=min(l,(double)a[i]);r=max(r,(double)a[i]);    }    while(l+eps<=r)    {        double mid=(l+r)/2;        if(check(mid)) l=mid;        else r=mid;    }    LL t=gcd(AA,BB);AA/=t;BB/=t;    if(BB<0) AA=-AA,BB=-BB;    printf("%lld/%lld",AA,BB);}
原创粉丝点击