E. Stack Sorting Codeforces(全排列与栈辅助排序)

Educational Codeforces Round 35 (Rated for Div. 2)

题目链接:http://codeforces.com/contest/911/problem/E

E. Stack Sorting
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard 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 calledstack-sortable.

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

  1. Remove 3 from a and push it into s;
  2. Remove 1 from a and push it into s;
  3. Remove 1 from s and append it to the end of b;
  4. Remove 2 from a and push it into s;
  5. Remove 2 from s and append it to the end of b;
  6. 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 kelements 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 ≤ 2000001 ≤ k < n) — the size of a desired permutation, and the number of elements you are given, respectively.

The second line contains k integers p1p2, ..., 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
【题意】

大致可以理解为,你要构造一个1~n的全排列。题目给出你前k项,你要把剩下的构造出来。

规定1、从构造好的序列中,只能从第一个数按顺序取

2、有一个栈可以暂时保存数字。

遵照两种规定,每次往数列b中放一个数,使得最终数列b是升序的。

【分析】

通过多组示例分析可以得出一些规律。

从全排列开头开始取数字,这个数字x有三种去向

1.如果数列b的下一项恰好是x,那就让x加入b

2.不满足1时,考虑让x先入栈保存,但是x必须小于栈中任意元素,才能入栈。

3.不满足1,2时,这个全排列是构造不出来的。

模拟这个过程操作前k项,然后开始考虑栈中剩余数字。

栈中之所以有剩余是因为数列b中没有比他们小的数,那就从栈顶开始考虑,把小于栈顶的数加入b中。

执行完这一过程后,倒序把所有没加入的数字加入到b中即可。

【代码】

#include<bits/stdc++.h>
using namespace std;
int sta[202020];
int a[202020];
bool vis[202020];
int n,k;
int main()
{
    while(cin>>n>>k)
    {
        memset(sta,0,sizeof(sta));
        memset(vis,0,sizeof(vis));
        int flag=1,b=0,top=0;
        for(int i=1;i<=k;i++)
        {
            int x;cin>>x;
            a[i]=x;
            vis[x]=1;
            if(x==b+1)//->b
                b++;
            else if(top==0||x<sta[top-1])
                sta[top++]=x;
            else flag=0;
            while(top&&sta[top-1]==b+1)
            {
                b++;top--;
            }
        }
        if(flag==0)
        {
            cout<<-1<<endl;
            continue;
        }
        for(int i=1;i<=k;i++)
            cout<<a[i]<<" ";
        sta[top]=0;
        for(int i=top-1;i>=0;i--)
        {
            for(int j=sta[i]-1;j>sta[i+1];j--)if(!vis[j])
            {
                cout<<j<<" ";
                vis[j]=1;
            }
        }
        for(int j=n;j;j--)if(!vis[j])
            cout<<j<<" ";
        cout<<endl;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪的期许

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值