MAX Average Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4762 Accepted Submission(s): 1185
Problem Description
Consider a simple sequence which only contains positive integers as a1, a2 ... an, and a number k. Define ave(i,j) as the average value of the sub sequence ai ... aj, i<=j. Let’s calculate max(ave(i,j)), 1<=i<=j-k+1<=n.
Input
There multiple test cases in the input, each test case contains two lines.
The first line has two integers, N and k (k<=N<=10^5).
The second line has N integers, a1, a2 ... an. All numbers are ranged in [1, 2000].
The first line has two integers, N and k (k<=N<=10^5).
The second line has N integers, a1, a2 ... an. All numbers are ranged in [1, 2000].
Output
For every test case, output one single line contains a real number, which is mentioned in the description, accurate to 0.01.
Sample Input
10 6 6 4 2 10 3 8 5 9 4 1
Sample Output
6.50
Source
Recommend
chenrui
#include<stdio.h>
#include<string.h>
int n,k,dp[100005],a[100005];
double sum[100005];
struct point{
double x,y;
}q[100005];
int check(point a,point b,point c)//判断某点是在直线上还是直线下,其实就是判断这个点加入后斜率是增大还是减小的
{
if((c.y-b.y)*(b.x-a.x)-(c.x-b.x)*(b.y-a.y)>0)
return 1;
return -1;
}
double rmax(double i,double j)
{
return i>j?i:j;
}
int scan()
{
int i=0;
char c;
while((c=getchar())!='\n'&&c!=' ')
{
i=i*10+c-'0';
}
return i;
}
int main()
{
int i,j,k,s,e;
double max;
point tem,tem2;
while(scanf("%d%d",&n,&k)!=EOF)
{
getchar();
max=-1;
memset(sum,0,sizeof(sum));
a[0]=0;
for(i=1;i<=n;i++)
{
a[i]=scan();;
sum[i]=sum[i-1]+a[i];//求和后可以简化运算
}
s=e=0;
for(j=k;j<=n;j++)//转化成直角坐标系
{
tem.y=sum[j-k];
tem.x=j-k;
while(s<e&&check(q[e-1],q[e],tem)<0)//单调队列,斜率逐渐增大的排到队尾,
e--;
q[++e]=tem;
tem2.x=j;
tem2.y=sum[j];
while(s<e&&check(q[s],q[s+1],tem2)>0)
s++;
max=rmax((double)(q[s].y-tem2.y)/(q[s].x-tem2.x),max);//斜率变大前面的点向后移动
}
printf("%.2f\n",max);
}
return 0;
}