Educational Codeforces Round 35 E. Stack Sorting

原题:
E. Stack Sorting
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Let’s suppose you have an array a, a stack s (initially empty) and an array b (also initially empty).

You may perform the following operations until both a and s are empty:

Take the first element of a, push it into s and remove it from a (if a is not empty);
Take the top element from s, append it to the end of array b and remove it from s (if s is not empty).
You can perform these operations in arbitrary order.

If there exists a way to perform the operations such that array b is sorted in non-descending order in the end, then array a is called stack-sortable.

For example, [3, 1, 2] is stack-sortable, because b will be sorted if we perform the following operations:

Remove 3 from a and push it into s;
Remove 1 from a and push it into s;
Remove 1 from s and append it to the end of b;
Remove 2 from a and push it into s;
Remove 2 from s and append it to the end of b;
Remove 3 from s and append it to the end of b.
After all these operations b = [1, 2, 3], so [3, 1, 2] is stack-sortable. [2, 3, 1] is not stack-sortable.

You are given k first elements of some permutation p of size n (recall that a permutation of size n is an array of size n where each integer from 1 to n occurs exactly once). You have to restore the remaining n - k elements of this permutation so it is stack-sortable. If there are multiple answers, choose the answer such that p is lexicographically maximal (an array q is lexicographically greater than an array p iff there exists some integer k such that for every i < k qi = pi, and qk > pk). You may not swap or change any of first k elements of the permutation.

Print the lexicographically maximal permutation p you can obtain.

If there exists no answer then output -1.

Input
The first line contains two integers n and k (2 ≤ n ≤ 200000, 1 ≤ k < n) — the size of a desired permutation, and the number of elements you are given, respectively.

The second line contains k integers p1, p2, …, pk (1 ≤ pi ≤ n) — the first k elements of p. These integers are pairwise distinct.

Output
If it is possible to restore a stack-sortable permutation p of size n such that the first k elements of p are equal to elements given in the input, print lexicographically maximal such permutation.

Otherwise print -1.

Examples
input
5 3
3 2 1
output
3 2 1 5 4
input
5 3
2 3 1
output
-1
input
5 1
3
output
3 2 1 5 4
input
5 2
3 4
output
-1

中文:

有n个从1到n的连续数,现在先给出其中k个数,让你用栈来实现对这n个数排序,给出一个可以使用栈来实现排序的顺序,要求字典序最大,其中先给出的k个数为最先输入的数据,顺序不能改变,如果可以使用栈排序,输出序列,否则输出-1。

#include<bits/stdc++.h>
using namespace std;
stack<int> st;
int a[200001];
bool mark[200001];
int n, k;
int main()
{
    ios::sync_with_stdio(false);
    while (cin >> n >> k)
    {
        while (!st.empty())
            st.pop();
        memset(a, 0, sizeof(a));
        memset(mark, 0, sizeof(mark));
        for (int i = 1; i <= k; i++)
        {
            cin >> a[i];
            mark[a[i]] = true;
        }
        int t = 1;
        int o = 0, flag = 0;
        while (true)
        {
            if (t <= k)
            {
                if (st.empty()||a[t]<st.top())
                {
                    if (a[t] - o != 1)
                    {
                        st.push(a[t]);
                        mark[a[t]] = true;
                        t++;
                    }
                    else//输出
                    {
                        o = a[t++];
                        mark[o] = true;//
                        while (!st.empty()&&st.top() - o == 1)
                        {
                            o = st.top();
                            st.pop();
                        }
                    }
                }
                else//栈顶元素比后续大
                {
                    flag = 1;
                    break;
                }
            }
            else
            {
                break;
            }
        }
        if (flag == 0)
        {
            for (int j = 1; j <= k; j++)
            {
                if (j != k)
                    cout << a[j] << " ";
                else
                    cout << a[j];
            }
            int pre=1;
            while(!st.empty())
            {
                for(int j=st.top()-1;j>=pre;j--)
                {
                    if(!mark[j])
                    {
                        cout<<" "<<j;
                        mark[j]=true;
                    }
                }
                pre=st.top();
                st.pop();
            }

            for (int j = n; j >= 1; j--)
                if (!mark[j])
                    cout << " " << j;
        }
        else
        {
            cout << -1;
        }
        cout << endl;
    }
    return 0;
}

解答:

cf上的e题居然这么简单~

简单的模拟栈的过程就好,先处理前k个给定的序列,判断能否按照栈的功能实现,然后按照栈顶元素的值,依次从大到小输出序列。
例如,有n=6,k=2 给定序列5 3

|  |
|3 |
|5 |
|__|(这是个栈)

先输出5,3 栈顶元素为3,那么可以安排序列 2 ,1 ,弹出3,栈顶元素为5 输出4,弹出5 输出6

最后结果就是
5,3 ,2,1,4,6

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值