洛谷P2947 向右看齐Look Up 题解 单调栈/单调队列
题目链接:https://www.luogu.com.cn/problem/P2947
题目大意:
约翰的 \(N(1 \le N \le 10^5)\) 头奶牛站成一排,奶牛\(i\)的身高是\(H_i(l \le H_i \le 1,000,000)\).现在,每只奶牛都在向右看齐.对于奶牛\(i\),如果奶牛\(j\)满足 \(i \lt j\) 且 \(H_i \lt H_j\) ,我们可以说奶牛\(i\)可以仰望奶牛\(j\) . 求出每只奶牛离她最近的仰望对象.
解题思路:
维护一个单调非递增的 单调队列 ,然后每次在第 \(i\) 投奶牛入队列之前,判断对位元素是否要出队,如果要出队,则对位元素的仰望对象就是 \(i\)。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, h[maxn], target[maxn];
deque<int> que;
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> h[i];
for (int i = 1; i <= n; i ++) {
while (!que.empty() && h[que.back()] < h[i]) {
target[que.back()] = i;
que.pop_back();
}
que.push_back(i);
}
for (int i = 1; i <= n; i ++) cout << target[i] << endl;
return 0;
}
因为进出元素都是队尾执行,所以我们可以用 单调栈 来实现同样的功能。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, h[maxn], target[maxn];
stack<int> stk;
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> h[i];
for (int i = 1; i <= n; i ++) {
while (!stk.empty() && h[stk.top()] < h[i]) {
target[stk.top()] = i;
stk.pop();
}
stk.push(i);
}
for (int i = 1; i <= n; i ++) cout << target[i] << endl;
return 0;
}