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 1000000000
using 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;
}