NC14893 栈和排序
题目
题目描述
给你一个1->n的排列和一个栈,入栈顺序给定
你要在不打乱入栈顺序的情况下,对数组进行从大到小排序
当无法完全排序时,请输出字典序最大的出栈序列
输入描述
第一行一个数 \(n\)
第二行 \(n\) 个数,表示入栈的顺序,用空格隔开,结尾无空格
输出描述:
输出一行 \(n\) 个数表示答案,用空格隔开,结尾无空格
示例1
输入
5
2 1 5 3 4
输出
5 4 3 1 2
说明
2入栈;1入栈;5入栈;5出栈;3入栈;4入栈;4出栈;3出栈;1出栈;2出栈
题解
知识点:栈,前缀和。
要得到最大字典序,那就要尽可能让大的数字靠前。由于栈是先进先出的,可以有限地控制一段序列顺序。如果一个元素,他之后没有更大的元素,入栈以后就必须出栈,否则他必然会在比他小的元素之后出栈,不是最优;如果有更大元素则不能出栈,不然大元素无法在前面,也不是最优的。
对此,我们需要知道第 \(i\) 个元素及以后的最大值,即后缀最大值 \(maxa[i]\)。对第 \(i\) 个元素,先入栈 \(s\),若\(s.top() < max[i+1]\) 则出栈,否则不出栈。
时间复杂度 \(O(n)\)
空间复杂度 \(O(n)\)
代码
#include <bits/stdc++.h>
using namespace std;
stack<int> s;
int a[100007], maxa[100007];
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 0;i < n;i++) cin >> a[i];
for (int i = n - 1;i >= 0;i--) maxa[i] = max(a[i], maxa[i + 1]);
for (int i = 0, j = 0;i < n;i++) {
s.push(a[i]);
while (!s.empty() && maxa[i + 1] < s.top()) cout << s.top() << ' ', s.pop();
}
while (!s.empty()) cout << s.top() << ' ', s.pop();
return 0;
}
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16436242.html