USACO-仰视奶牛

题意

约翰有N头奶牛,编号为1到N。

现在这N头奶牛按编号从小到大的顺序站成了一排,其中奶牛 i 的身高为Hi。

现在,每头奶牛都向它的右侧望向那些编号较大的奶牛,对于奶牛 i 如果存在一头奶牛 j 满足 i<j 并且 Hi<Hj,那么我们称奶牛 i 需要仰视奶牛 j。

请你求出每头奶牛的最近仰视对象。

输入格式
第一行包含整数N。

接下来N行,每行包含一个整数Hi,其中第 i 行的数为编号为 i 的奶牛的高度。

输出格式
共 N 行,每行输出一个整数,其中第 i 行的输出整数表示编号为 i 的奶牛的最近仰视对象的编号,如果不存在仰视对象,则输出0。

数据范围
1≤N≤105,
1≤Hi≤106

样例

输入样例:
6 
3 
2 
6 
1 
1 
2 
输出样例:
3 
3 
0 
6 
6 
0

知识

单调栈的运用

思路

这题相对简单,这是一个入门题目。我以前觉得只要会模板,什么都可以做出来,但其实是不可能的,我们不能太依靠模板。这个是我复习写的题解。我们需要掌握单调栈的思想,这里我给出一个博客——单调栈,我个人觉得讲的相对很好。题意略过,直接说怎么做。
题意是牛牛们右边有比他们高并且最近的小母牛吗?如果有的话,记录位置。我们可以看出有单调性趋向。
比如 3 2 6,这三只牛牛们,记录位置的答案为 3 3 0。就是从3的本身来说,我们设置未知变量X,只有当 X>3 的时候,那么这个本身从数学上来说,就是一个递增的过程。然后哦单调栈刚好符合这一特性,单调更新。

代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <utility>
#include <queue>
#define Re(i,a,b) for(int i=(a);i<=(b);i++)
#define PII pair<int,int> 
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define hh "\n"

using namespace std;
const int N=1e5+10;
int p[N],d[N];

int main (){
	IOS;//宏定义
    int n;
    cin>>n;
    Re(i,1,n) cin>>p[i];
    stack<PII> tt;//数据结构的使用
    Re(i,1,n){
    	while(tt.size()&&p[i]>tt.top().first){//这里的判断才是精髓,
    	//只有当右边的数值大于栈顶数值得时候,数据更新。
    	//这里的判断维持单调递增的特性
    		d[tt.top().second]=i;//保存数据
    		tt.pop();
		}
		tt.push({p[i],i});
	}
	Re(i,1,n) cout<<d[i]<<hh;
    return 0;
}

蟹蟹,欢迎指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值