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;
}
posted @ 2022-07-01 23:28  空白菌  阅读(92)  评论(0编辑  收藏  举报