组题
Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 542 Solved: 114
[Submit][Status][Discuss]
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
1 4 -2 -3 6
Sample Output
5/4
HINT
Source
题解:
二分答案,判断有没有长度大于等于k的正数段即可,选得越少答案越大。
1 #include<cstring> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdio> 6 7 #define ll long long 8 using namespace std; 9 inline int read() 10 { 11 int x=0,f=1;char ch=getchar(); 12 while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();} 13 while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 17 int n,k,L,R,a[100005]; 18 double s[100005]; 19 ll A,G,len; 20 ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);} 21 bool judge(double mid) 22 { 23 int p=0;double mn=100000000000000,mx=0;bool flag=0; 24 for (int i=1;i<=n;i++) 25 { 26 s[i]=s[i-1]+1.0*a[i]-mid; 27 if (i>=k&&mn>s[i-k]) mn=s[i-k],p=i-k; 28 if (s[i]-mn>=mx){mx=s[i]-mn;L=p;R=i;flag=1;} 29 } 30 return flag; 31 } 32 int main() 33 { 34 n=read();k=read(); 35 for (int i=1;i<=n;i++) a[i]=read(); 36 double l=-100000005,r=100000005; 37 while (r-l>0.000001) 38 { 39 double mid=(l+r)/2; 40 if (judge(mid)) l=mid;else r=mid; 41 } 42 for (int i=L+1;i<=R;i++) A+=(ll)a[i];len=R-L; 43 G=gcd(abs(A),len); 44 A/=G;len/=G; 45 printf("%lld/%lld",A,len); 46 }