K-Stack
原题链接:https://ac.nowcoder.com/acm/contest/11253/K
题目大意
数组 b b b按排列 a a a按下列伪代码生成:
Stk is an empty stack
for i = 1 to n :
while ( Stk is not empty ) and ( Stk's top > a[i] ) :
pop Stk
push a[i]
b[i]=Stk's size
有一个长度为 n ( 1 ≤ n ≤ 1 0 6 ) n(1\le n\le10^6) n(1≤n≤106)的数组 b b b,只知道其中 k k k项,求排列 a a a.若有则输出任意一种即可,若没有则输出 − 1 -1 −1.
解题思路
对于一个合法的数组 b b b,一定可以求得一个排列 a a a,下面只介绍一种方法。
从第一个元素开始,如果没被填充,就是上一个元素加一。
从最后一个元素开始, 如果栈内没有 b i b_i bi个元素,压进,否则弹出。
当两个个元素之间的标号差小于元素差,则此 b b b数组不合法,输出 − 1 -1 −1。
代码实现
#include<bits/stdc++.h>
using namespace std;
stack<int>sta;
int n,k,b[1000001],a[1000001];
struct nn{
int x,y;
}x[1000001];
bool cmp(nn a,nn b)
{
return a.x<b.x;
}
int main()
{
cin>>n>>k;
for(int i=1;i<=k;i++){
cin>>x[i].x>>x[i].y;
b[x[i].x]=x[i].y;
}
sort(x+1,x+k+1,cmp);
for(int i=0;i<k;i++)
if(x[i+1].x-x[i].x<x[i+1].y-x[i].y)
{
puts("-1");
return 0;
}
for(int i=1;i<=n;i++)
{
if(b[i]==0)b[i]=b[i-1]+1;
}
int g=1;
for(int i=n;i>=1;i--)
{
while(sta.size()<b[i])sta.push(g++);
a[i]=sta.top(),sta.pop();
}
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
}