链接:https://ac.nowcoder.com/acm/contest/11253/K 来源:牛客网

题目描述

ZYT had a magic permutation a1,a2,⋯ ,an and he constructed a sequence b1,b2,⋯bn by the following pseudo code:

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

But he somehow forgot the permutation a, and only got some k elements of bi.

Construct a permutation a satisfying these bi , or determine no such permutation exists.

Here a permutation refers to a sequence that contains all integers from 1 to n exactly once.

输入描述:

The first line contains two integers n,k(1≤k≤n) — the length of the permutation, the number of  left bi.

Then k lines each contains two integer pi,xi denoting that bpi=xi.

输出描述:

Output one line with n integers a1,a2,⋯an — a possible permutation.

If no such permutation exists, output one integer -1.

示例1

输入

5 2
2 2
5 4

输出

1 2 5 3 4

其实这里的输出样例为1 2 3 5 4 也是可以的,1 2 3 5 4 的输出反而更好理解。

示例2

输入

10 1
1 10

输出

-1

备注:

It's guaranteed that n≤10^6,1≤pi,xi≤n, and ∀i≠j,pi≠pj.

思路:

题意是输出一个符合条件的a数组,保证a数组内元素按照要求依次入栈,第i步操作后栈内元素个数符合b数组对应b[i]的值。

按照伪代码的要求,当栈顶元素大于将要入栈的a[i]的值时,栈顶元素出栈,直到栈顶元素小于等于将要入栈的a[i]的值(注意这里是一个while循环,有可能会一直出栈,所以b数组内后面的元素值比前面的值小是有可能的)。当栈顶元素不大于将要入栈的a[i]的值时,a[i]入栈,更新b[i]为新的栈的大小。

其实也就是一个反推的过程,不理解的话可以手算一下。

但是如果写模拟的代码,可能会超时(当时写的时候确实是超时了,结束之后看别人的代码发现还是有人写模拟的,应该是写的方法问题,需要优化算法)。干脆直接对数组进行操作。

另外要注意,当出现pi的值小于xi的情况,例如pi=2,xi=5,正常情况应该是b2=2,想要在第二次操作b2时实现栈内有5个数,肯定是不可能实现的,当前最多只有2个数。这种情况就要输出-1。

代码:

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
int main() {ios::sync_with_stdio(false);  int n,k;cin>>n>>k;vector<int> b(n+1);while(k--){int p,x;cin>>p>>x;b[p] = x;}int temp = 0;for(int i=1;i<=n;i++){temp++;if(b[i] > 0){if(b[i] > temp){   //当前位置与数字不匹配 cout << "-1\n";return 0;}temp = b[i];}else b[i] = temp;  //根据所给数据填补b数组 }vector<int> a(n+2);for(int i=1;i<=n;i++){a[b[i]]++;          //记录需要变更的数 }for(int i=2;i<=n+1;i++){a[i] += a[i - 1]; //累加前一个的数 }for(int i=1;i<=n;i++) {cout << a[b[i]]-- <<" ";}cout<<'\n';return 0;
}

另外还有类似模拟的代码,附在下面参考

#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int n,k;
int a[N],b[N],res[N];
stack<int>s;
stack<int>t;int main()
{scanf("%d%d",&n,&k);memset(b,0,sizeof(b));for(int i=0;i<k;i++){ int p,x;scanf("%d%d",&p,&x);b[p] = x;}int temp = 0,flag = 0;while(!s.empty()) s.pop();    //清空栈 while(!t.empty()) t.pop();    //清空栈for(int i=1;i<=n;i++){temp++;if(b[i] != 0){if(temp < b[i]){   //当前位置与数字不匹配 flag = 1;     //设置标记 break;}int cnt = temp - b[i];for(int j=0;j<cnt;j++){t.push(s.top());s.pop();}temp = b[i];}s.push(i);}int tot = 1;if(flag){printf("-1\n");return 0;}while(!s.empty()){t.push(s.top());s.pop();}while(!t.empty()){res[t.top()] = tot++;t.pop();}for(int i=1;i<=n;i++){printf("%d",res[i]);if(i != n) printf(" ");else printf("\n");}return 0;
}

K-Stack 2021牛客多校2相关推荐

  1. LCS(2021牛客多校4)

    LCS(2021牛客多校4) 题意: 让你构造三个字符串s1,s2,s3,长度均为n,要求LCS(s1,s2)=a,LCS(s2,s3)=b,LCS(s1,s3)=c 题解: 先考虑三个串互相LCS为 ...

  2. 【2021牛客多校2】F-Girlfriend 计算几何

    2021牛客多校2-F F-Girlfriend 题目大意 给出四个点 A , B , C , D A, B, C, D A,B,C,D 另有两点 P 1 , P 2 P_1, P_2 P1​,P2​ ...

  3. 2021牛客多校第五场补题

    B-Boxes 链接:https://ac.nowcoder.com/acm/contest/11256/B 来源:牛客网 题目描述 There're nn_{}n​ boxes in front o ...

  4. 2021牛客多校第八场补题 D-OR

    链接:https://ac.nowcoder.com/acm/contest/11259/D 来源:牛客网 题目描述 There are two sequences of length n−1n-1n ...

  5. 【多校训练】2021牛客多校第二场

    [前言] 这是打的第二场,rk39,但是AB这两个比较简单的题都没做emm,大概还是磨合的不够.然后感觉对于阈值类的东西还不是很敏感,应该看到不太好做就直接去想这种阈值的.校内3/9(然后就开启了常年 ...

  6. 2021牛客多校2 - Stack(单调栈+拓扑)

    题目链接:点击查看 题目大意:给出 b[i]b[i]b[i] 数组的求解过程: Stk is an empty stack for i = 1 to n :while ( Stk is not emp ...

  7. 2021牛客多校9 - Cells(推公式+NTT)

    题目链接:点击查看 题目大意:初始时给出 nnn 个点,分别为 {(0,a0),(0,a1),⋯,(0,an)}\{(0,a_0),(0,a_1),\cdots,(0,a_n)\}{(0,a0​),( ...

  8. 【多校训练】2021牛客多校5

    [前言] 很久没有时间整理题解了,补题和打游戏的时间居多(doge) 这场其实主要F出题人数据有锅,花太多时间了(赛后重测是一血),然后后面G想歪了爆搜剪枝没过,I的回滚莫队队友前一天写了结果今天写不 ...

  9. 2021牛客多校10 - Browser Games(哈希)

    题目链接:点击查看 题目大意:给出 nnn 个字符串,对于每个 iii ,输出最少需要用多少个前缀,可以表示第 1∼i1\sim i1∼i 个字符串而不能表示第 i+1∼ni+1\sim ni+1∼n ...

最新文章

  1. 如何利用 C# 爬取 One 持有者返利数据!
  2. 蓝桥杯:入门训练 圆的面积
  3. Linux有问必答:如何安装autossh
  4. Zookeeper--ZAB与Paxos算法联系与区别
  5. Python | threading05 - 使用有界信号量,实现线程间同步
  6. 快速实现手势解锁功能
  7. Android中的savedInstanceState
  8. JDK 环境变量配置
  9. rabbitmq java代码_RabbitMQ java 原生代码
  10. 计算机专硕超过270分人数,从18调剂看19备考策略(附76所院校19招生简章)
  11. vim编辑器-缩进修改
  12. 麦咖啡企业版McAfee VirusScan Enterprise v8.8授权版
  13. Windows下使用CMD下载网络文件
  14. plecs使用C-Script模块建立PI传递函数模型
  15. Quartus之仿真错误#** Error (suppressible): (vsim-19) Failed to access library ‘ ‘ at “ “
  16. 警告:integer division in floating-point context
  17. element-ui el-date-picker日期选择器 value-format问题
  18. openGL曲面细分
  19. 常见Shell编程脚本
  20. 基于BERT+BiLSTM+CRF的中文景点命名实体识别

热门文章

  1. 【转载】通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
  2. 燃尽图 (Burn up and Burn down Chart)—介绍
  3. 介绍几种等待多线程任务执行完毕的方法
  4. sefan ru java games_Java Pinyin.se4方法代码示例
  5. excel服务器条形码不显示,excel怎么制作条形码教程 excel条形码显示不出怎么办...
  6. 谷歌浏览器突然不能翻译了怎么解决?无法翻译此网页的解决方法
  7. 关于华为应用市场审核App无法启动的问题
  8. 蓝桥杯 算法提高 矩阵乘方
  9. 微信小程序如何加密?
  10. 关于Win10家庭版安装VirtualBox时的一些问题(e.g.报错2203)