Stack

在这里插入图片描述

构造解的问题太难了,,,看了好久没有注释的大佬代码,才大概清楚了,,

根据题目给的伪代码,我们可以知道,栈中的元素个数是单调不减的,并且栈中元素个数绝对不会超过遍历的下标i(下标从1开始),如果超过就不存在解,那么这又有什么用呢,,既然是单调不减的,那么我们可以把位置的栈元素个数求出来,剩下的看代码,不太好表达出来。。其实就是还没完全懂

AC代码:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    
    ios_base::sync_with_stdio(false);
    
    int n,k;
    cin >> n >> k;
    vector<int> b(n+1);
    
    int q,v;
    for(int i = 1;i<=k;i++){cin >> q >> v; b[q] = v;} //先把已经知道的放入对应的位置
    
    int cnt = 0;
    for(int i = 1;i<=n;i++){     //因为是单调不减的,所以我们可以把每个位置在栈中的个数求出来
        cnt++;
        if(b[i] > 0){
            if(b[i] > cnt){    //当前位置的栈元素个数绝对不会超过cnt,超过了就说明不存在
                cout << -1 << endl;
                return 0;
            }
            cnt = b[i];//保持单调不减的性质
        }else b[i] = cnt;
    }
    
    vector<int> ans(n+1);
    
    for(int i = 1;i<=n;i++){
        ans[b[i]]++;//把每个栈元素个数出现的次数求出来
    }
    for(int i = 1;i<=n;i++) ans[i] += ans[i-1]; //构造解,这里就不太好理解了
    
    for(int i = 1;i<=n;i++) cout << ans[b[i]]-- << " \n"[i == n]; 
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值