【bzoj5090】组题

来源:互联网 发布:免费顶级域名注册 ml 编辑:程序博客网 时间:2024/05/20 13:04

Description

著名出题人小Q的备忘录上共有n道可以出的题目,按照顺序依次编号为1到n,其中第i道题目的难度系数被小Q估计
为a_i,难度系数越高,题目越难,负数表示这道题目非常简单。小Q现在要出一套难题,他决定从备忘录中选取编
号连续的若干道题目,使得平均难度系数最高。当然,小Q不能做得太过分,一套题目必须至少包含k道题目,因此
他不能通过直接选取难度系数最高的那道题目来组成一套题。请写一个程序,帮助小Q挑选平均难度系数最高的题
目。
Input

第一行包含两个整数n,k(1<=n<=100000,1<=k<=n),分别表示题目的总量和题数的下界。

第二行包含n个整数a_1,a_2,…,a_n(|a_i|<=10^8),分别表示每道题目的难度系数。
Output

输出一个既约分数p/q或-p/q,即平均难度系数的最大值。

Sample Input

5 3

1 4 -2 -3 6
Sample Output

5/4

题解
二分平均数
判断:每个数减去mid(二分值)判断是否存在一段(>=k)连续值和>0

代码

#include<bits/stdc++.h>#define ll long long#define inf 1000000000using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int n,k,L,R,a[100005];double s[100005];ll A,G,len;ll gcd(ll a,ll b){return (b==0)?a:gcd(b,a%b);}bool judge(double mid){    int p=0;double mn=100000000000000,mx=0;bool flag=0;    for (int i=1;i<=n;i++)    {        s[i]=s[i-1]+1.0*a[i]-mid;        if (i>=k&&mn>s[i-k]) mn=s[i-k],p=i-k;        if (s[i]-mn>=mx){mx=s[i]-mn;L=p;R=i;flag=1;}    }    return flag;}int main(){    n=read();k=read();    for (int i=1;i<=n;i++) a[i]=read();    double l=-100000005,r=100000005;    while (r-l>0.000001)    {        double mid=(l+r)/2;        if (judge(mid)) l=mid;else r=mid;    }    for (int i=L+1;i<=R;i++) A+=(ll)a[i];len=R-L;    G=gcd(abs(A),len);    A/=G;len/=G;    printf("%lld/%lld",A,len);    return 0;}
原创粉丝点击