在O(logn)时间内找到数组中离每个数最近而又比它大的数的下标
来源:互联网 发布:德客会员管理系统源码 编辑:程序博客网 时间:2024/06/05 05:06
题目描述
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.
示例输入
77 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;}
0 0
- 在O(logn)时间内找到数组中离每个数最近而又比它大的数的下标
- 找出数组中每个数的右边第一个比它大的数
- 在O(n)时间内找到数组中任意第K小的数
- 【二分查找】在一个长度未知的数组中查找一个数,返回其下标,时间复杂度O(logn)
- Next Greater Element I(在数组中找到比给定数大的下一个数)
- Next Greater Element II(在数组中找到比给定数大的下一个数)
- 输入一组数据,在输入一个数,找到比它大的并排序
- 【二分查找】查找数组中第一个比k大的数的下标
- 【二分查找】查找数组中第一个比k大的数的下标
- 找到比给定数大的数
- 在无序数组中找到第k大的数
- 数组中存在这样的数,这个数比它左边的所有的数大,并且比它右边的所有的数小,返回它的索引;如果不存在,返回-1
- 如果数组中存在这样的数,这个数比它左边的所有的数大,并且比它右边的所有的数小,返回它的索引;如果不存在,返回-1。
- 在一个有序数列中找到第一个比x大的数的位置
- 找出数组中有元素比它的邻居大的元素下标
- 找到比一个数大的距离最近的2的n次方的值
- Inversion Sequence 已知逆序数(前面比它大的数的个数),还原数组
- 一个数组中列出一个数比前面数大,比后面数小的集合
- 饼图表定义
- Unity3d中使用OnGUI()函数判断“键盘按下抬起”功能的新方法。
- CentOS 6 安装在虚拟机上 eth0网卡无法工作的解决
- csu1673 集训队组队计划 (二分)
- C语言内嵌汇编(arm-v7)----加减乘移位
- 在O(logn)时间内找到数组中离每个数最近而又比它大的数的下标
- 按钮权限分配
- C++基本概念——聊聊C++中的函数匹配那些事儿
- 第一次
- AC自动机概述
- 快速排序
- 在 java web 中调用存储过程
- [BZOJ2527][Poi2011]Meteors
- nyoj--635--Oh, my goddess(dfs)