题意
约翰有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;
}
蟹蟹,欢迎指正