HZNUOJ 1472 The nearest taller cow

1472: The nearest taller cow

Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 151  Solved: 6  Scores: 94.48

Description

Farmer Zhao’s N cows (1 ≤ N ≤ 1,000,000) are lined up in a row. So each cow can see the nearest cow which is taller than it. You task is simple, given the height (0 < height ≤ 109) of each cow lined up in the row, to calculate the distance between each cow and its nearest taller cow (the nearest cow which is taller than him), if it is the tallest cow in the row, such distance is regarded as n. You should output the average distance.

Input

For each test case:

Line 1: One integers, N

Lines 2: N integers. The i-th integer is the height of the ith cow in the row.

Output

The average distance to their nearest taller cow, rounded up to 2 decimals.

Sample Input

7
7 6 5 8 6 4 10

Sample Output

2.43

HINT

You may suffer a precision problem. To ensure that you can output a correct answer on OJ(Online Judge), please write your output statements like it:

#define eps 1e-7

……

printf(“%.2f\n”,sum/n+eps);

——noted by CYP

Author

Source

湖南大学2009校赛

这题直接暴力会超时,可以这么优化。
两个方向各扫一遍,以向右扫为例,遍历第i头牛的时候,顺路把它的答案记下来,那么在接下来的扫描中,如果a[i]>=a[j],那么j可以直接跳到l[j],因为如果l[j]=k且a[i]>=a[j],那么k-1~j肯定也比a[i]小,故可以直接跳过。

AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define EPS 1e-8
const int MAX=1000000+100;

int a[MAX],l[MAX],r[MAX];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=1 ; i<=n ; ++i)
        {
            scanf("%d",&a[i]);
        }
        a[0]=a[n+1]=0x7fffffff;
        l[1]=0;
        for(int i=2 ; i<=n ; ++i)
        {
            int j=i-1;
            while(a[i]>=a[j])
            {
                j=l[j];
            }
            l[i]=j;
        }
        r[n]=n+1;
        for(int i=n-1 ; i>=1 ; --i)
        {
            int j=i+1;
            while(a[i]>=a[j])
            {
                j=r[j];
            }
            r[i]=j; 
        }
        long long sum=0;
        for(int i=1 ; i<=n ; ++i)
        {
            if(r[i]==n+1 && l[i]==0)
            {
                sum+=n;
            }
            else if(r[i]==n+1)
            {
                sum+=i-l[i];
            }
            else if(l[i]==0)
            {
                sum+=r[i]-i;
            }
            else
            {
                sum+=min(r[i]-i,i-l[i]);
            }
        }
        printf("%.2f\n",(double)sum/n+EPS);
    }
    return 0;
}

你可能感兴趣的:(算法,ACM)