hdu 2993 MAX Average Problem

MAX Average Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4748    Accepted Submission(s): 1180


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].
 

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 <iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define positive(a) ((a)>0?(a):-(a))
using namespace std;
double sum[100100];//存前i项的和
int n,k,head,tail;
double ans;
struct node//队列
{
    double val;
    int id;
} q[100100];

inline int GetInt()//读入优化,否则超时
{
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        ch = getchar();
    }
    int num = 0;
    while (ch >= '0' && ch <= '9')
    {
        num = num * 10 + ch - '0';
        ch = getchar();
    }
    return num;
}
void solve()
{
    int i,j;
    double x1,y1,x2,y2;
    double temp;
    head=tail=0;
    ans=-1;
    for(i=k;i<=n;i++)
    {
        j=i-k;
        while(tail-head>=2)
        {
            x2=j-q[tail-1].id;
            y2=sum[j]-q[tail-1].val;
            x1=q[tail-1].id-q[tail-2].id;
            y1=q[tail-1].val-q[tail-2].val;
            if(x2*y1-y2*x1>=0)//原始为y1/x1<=y2/x2即加入j后形成上突点
                tail--;//删除上凸点
            else
                break;
        }
        q[tail].id=j;//加入新点
        q[tail++].val=sum[j];
        while(tail-head>=2)
        {
            x2=i-q[head+1].id;
            y2=sum[i]-q[head+1].val;
            x1=i-q[head].id;
            y1=sum[i]-q[head].val;
            if(y2*x1-y1*x2>=0)//y2/x2>=y1/x1若上可选点斜率小于下一可选点
                head++;
            else
                break;
        }
        temp=(sum[i]-q[head].val)/(i-q[head].id);
        ans=MAX(ans,temp);
    }
}
int main()
{
    int i,a;

    while(~scanf("%d%d",&n,&k))
    {
        memset(sum,0,sizeof sum);
        for(i=1;i<=n;i++)
        {
            a=GetInt();
            sum[i]=sum[i-1]+a;
        }
        solve();
        printf("%.2lf\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值