MAX Average Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5613 Accepted Submission(s): 1389
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
题意:给出一个序列,求出在所有长度至少为k的子区间中平均值最大的值。
思路:我们要求的就是 max((sum[i]-sum[j])/(i-j),把对应的(i,sum[i]) 放到坐标系中,发现什么没有?这个表示是一个斜率,就是说求出这些点的最大斜率, 而且可以看出sum是单调递增的。那么我们能用O(n) 的时间求出最大斜率,详细的解答请看《浅谈数形结合思想在信息学竞赛中的应用》,里面说的很详细。。。。 注意,这道题读取的时候用getchar, 会快很多,不然你交去G++会TLE的。
代码:
#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<queue>
using namespace std;
const int maxn = 100000 + 5;
#define LL long long
int n, k;
int sum[maxn];
int q[maxn];
inline double max(double a, double b) { return a > b ? a : b; }
inline LL up(int i, int j) { return sum[i] - sum[j]; }
inline LL down(int i, int j) { return i - j; }
void GetInt(int & a)
{
a = 0;
char ch;
while (ch = getchar() , (ch<'0' || ch>'9'));
while ('0' <= ch&&ch <= '9')
{
a = a * 10 + ch - '0';
ch = getchar();
}
}
void input()
{
sum[0] = 0;
for (int i = 1; i <= n; ++i) { GetInt(sum[i]); sum[i] += sum[i - 1]; }
}
void solve()
{
int front = 0, rear = 0;
q[rear++] = 0;
double ans = 0;
for (int i = k; i <= n; ++i)
{
int j = i - k + 1;
while (rear - front > 1 && up(q[front], i)*down(q[front + 1], i) <= up(q[front + 1], i)*down(q[front], i)) ++front;
ans = max(ans, (double)up(i, q[front]) / down(i, q[front]));
while (rear - front > 1 && up(q[rear - 1], q[rear - 2])*down(j, q[rear - 1]) > up(j, q[rear - 1])*down(q[rear - 1], q[rear - 2])) --rear;
q[rear++] = j;
}
printf("%.2lf\n", ans);
}
int main()
{
while (scanf("%d%d", &n, &k) == 2)
{
input();
solve();
}
}