Acwing 600. 仰视奶牛(stack记录成对数写法)(每头奶牛的最近仰视对象)

地址:https://www.acwing.com/problem/content/602/

既然是离自己最近,可以想到栈

对于当前数,把它左边数的视为栈。

每次ai与栈顶比较,

如果发现栈顶<ai,说明它可以被栈顶仰视,记录下标。同时清掉栈顶。为什么要清掉呢?因为题目要求的是找最近,既然栈顶已经找到最近答案,后续就用不到它了,所以清掉即可。

否则,while结束。为什么结束?因为栈顶大于>=ai的话,栈里其他的元素也一定大于等于ai,因为我们建立的是一个单调队列。假设有a1<a2,那么根据第一步,a1被清掉,再次加入一个a3,而且a3<a2,那么此时栈有:a2,a3。再加入一个a4<a3,那么a4也只能入栈,栈里的元素,均大于a4,while也就没必要继续了。

#include<cstdio>
#include<cstring>
#include<vector>
#include<set>
#include<stack>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=1e5+10,maxn2=31*maxn;
int st[maxn],tt,n,a[maxn],b[maxn];
stack<pair<int,int> > s;
struct node
{
    int x,id;
}h[maxn];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        while(!s.empty()&&a[i]>s.top().first)
        {
            b[s.top().second]=i;
            s.pop();
        }
        s.push(make_pair(a[i],i));
    }
    for(int i=1;i<=n;i++)
    {
        cout<<b[i]<<endl;  
    }
}
原文地址:https://www.cnblogs.com/liyexin/p/13945972.html