题目描述
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, if it is the tallest cow in the row, such distance is regarded as n. You should output the average distance.
输入
For each test case:
Line 1: One integers, N
Lines 2: N integers. The ith integer is the height of the ith cow in the row.
Line 1: One integers, N
Lines 2: N integers. The ith integer is the height of the ith cow in the row.
输出
The average distance to their nearest taller cow, rounded up to 2 decimals.
示例输入
7 7 6 5 8 6 4 10
示例输出
2.43
y[p]指从p点往前找的第一个比它大的值的下标。
z[p]指从p点往后找的第一个比它大的值的下标。
分析一下为什么能省时间:假设当前点i,那么p从i-1开始往前找起,如果碰到x[p]比x[i]大的,那么就直接跳出循环给y[i]赋值;如果x[p]比x[i]小,提取y[p],那么易知从(y[p],p]这个区间内的所有值都比x[i]小(为什么?假如这个区间内有比x[i]大的值的话,y[p]'取区间内的下标比y[p]显然更优,这就产生矛盾)令p'=y[p],那就可以直接跳过这个区间从p'开始往前找了。
#include<bits/stdc++.h>
#define ll long long
#define EPS 1e-8
using namespace std;
int x[1000005];
int y[1000005];
int z[1000005];
int main(){
int n;
while(~scanf("%d",&n)){
x[0]=2000000000;
x[n+1]=2000000000;
for(int i=1;i<=n;++i){
scanf("%d",&x[i]);
int p=i-1;
while(x[p]<=x[i]){ //如果比它小,那么把坐标p移动到更前的y[p]继续找,缩短时间
p=y[p];
}
y[i]=p;
}
for(int i=n;i>=1;--i){
int p=i+1;
while(x[p]<=x[i]){
p=z[p];
}
z[i]=p;
}
double s=0;
for(int i=1;i<=n;++i){
if(y[i]==0) y[i]=-2000000000;
if(z[i]==n+1) z[i]=2000000000;
s+=min(min(i-y[i],z[i]-i),n);
}
printf("%.2f\n",s/n+EPS); //这题必须加EPS才能过
}
return 0;
}
本文介绍了一种算法,用于解决 FarmerZhao 的 N 头牛按高度排列时,每头牛与其最近的更高牛之间的平均距离计算问题。通过预先计算每个位置向前向后找到的第一个较高牛的位置,有效地减少了计算时间。
5万+

被折叠的 条评论
为什么被折叠?



