2021牛客暑期多校训练营2 K Stack

Source

题目大意:
题目告诉你利用单调栈几个点前面比它小并包含它自身的元素有多少个
让你构造一个包含1到n并每个数字只出现一次的序列

思路:
我们可以对于每个点都算出栈中元素的数量
对于没有给出的点的栈中元素的数量
我们直接让栈中的元素等于上个点的栈中的元素+1就好了
而对于给出点的栈的元素的时候我们首先要看他合不合法
如果栈中的元素数量是大于上一个点的栈中的元素数量+1的就说明填数填不进去了
这个时候就是不合法的
而得到每个点的栈中元素数量之后
我们可以从后往前遍历
看栈中元素的数量依次把1,2,3,4,5······按递增顺序放入栈里
因为单调栈元素中的数量代表的是递增数字的数量
那么当递增数字满了的时候即加入数字后等于栈中元素数量的时候
就直接把数字当做该点的值即可

AC代码:

#include <iostream>
#include <algorithm>
using namespace std;
int b[1000010];
int a[1000010];
int st[1000010];
int main()
{
    
      
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=k;i++){
    
      
        int pos;
        cin>>pos>>a[pos];
    }
    for(int i=1;i<=n;i++){
    
      
        if(!a[i])a[i]=a[i-1]+1;
        else if(a[i]>a[i-1]+1){
    
      
                cout<<"-1"<<endl;
                return 0;
        }
    }
    int cnt=0,top=0;
    for(int i=n;i>=1;i--){
    
      
        while(a[i]>top)st[++top]=++cnt;//++cnt能保证先把小的弹出来再把大的弹出来
        b[i]=st[top];
        top--;
    }
    for(int i=1;i<=n;i++)cout<<b[i]<<' ';
    return 0;
}