首先用模拟的方式来看已有的k个数字是否有可能构成递增数列。用一个
值b记录一下当前想要的数,如果可以从p[i]或者从堆栈里获得就不断把这个值b变大,如果遇到p[i]不满足b了,就把p[i]入栈,但是要求当前p[i]不能比栈里的值大,【(底)。。。小,大(顶)】的情况会导致小的数取不出来。
最后会发现栈里留下的是一个递减的序列。那么为了把栈顶的数弹出来,就必须获得比它小的数,用这样的方式这样依次弹栈。最后缺少的那一部分只要从大到小依次加入答案就可以。
#include<bits/stdc++.h>
using namespace std;
int p[200010], vis[200010];
int main(){
int n, k, b;
int stk[200010], stktop;
while(~scanf("%d%d", &n, &k)){
b=1;
stktop=0;
memset(vis, 0, sizeof(vis));
for(int i=0; i<k; i++)
scanf("%d", &p[i]);
int flag=1;
for(int i=0; i<k; i++){
vis[p[i]]++;
if(p[i]==b){
b++;
}
else{
if(stktop==0){
stk[stktop++]=p[i];
}
else{
int ttop=stk[stktop-1];
if(ttop<p[i]){
printf("-1\n");flag=-1;break;
}
else
stk[stktop++]=p[i];
}
}
while(stktop){
int ttop=stk[stktop-1];
if(ttop==b){
stktop--;b++;
}
else break;
}
}
if(flag==-1) continue;
for(int i=0; i<k; i++){
if(i) cout<<" ";
cout<<p[i];
}
stk[stktop]=0;
//一开始的做法太暴力所以超时了
for(int i=stktop-1; i>=0; i--){
for(int j=stk[i]-1; j>stk[i+1]; j--){
if(!vis[j]){
vis[j]++;
cout<<" "<<j;
}
}
}
for(int i=n; i>0; i--){
if(!vis[i])
cout<<" "<<i;
}
cout<<endl;
}
return 0;
}