题目描述

Tom最近在研究一个有趣的排序问题。如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序。

操作a

如果输入序列不为空,将第一个元素压入栈S1

操作b

如果栈S1不为空,将S1栈顶元素弹出至输出序列

操作c

如果输入序列不为空,将第一个元素压入栈S2

操作d

如果栈S2不为空,将S2栈顶元素弹出至输出序列

如果一个1~n的排列P可以通过一系列操作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”。例如(1,3,2,4)就是一个“可双栈排序序列”,而(2,3,4,1)不是。下图描述了一个将(1,3,2,4)排序的操作序列:<a,c,c,b,a,d,d,b>

当然,这样的操作序列有可能有几个,对于上例(1,3,2,4),<a,c,c,b,a,d,d,b>是另外一个可行的操作序列。Tom希望知道其中字典序最小的操作序列是什么。

输入输出格式

输入格式:

输入文件twostack.in的第一行是一个整数n。

第二行有n个用空格隔开的正整数,构成一个1~n的排列。

输出格式:

输出文件twostack.out共一行,如果输入的排列不是“可双栈排序排列”,输出数字0;否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。

输入输出样例

输入样例#1:

  1. 【输入样例1
  2. 4
  3. 1 3 2 4
  4. 【输入样例2
  5. 4
  6. 2 3 4 1
  7. 【输入样例3
  8. 3
  9. 2 3 1
输出样例#1:

  1. 【输出样例1
  2. a b a a b b a b
  3. 【输出样例2
  4. 0
  5. 【输出样例3
  6. a c a b b d

说明

30%的数据满足: n<=10

50%的数据满足: n<=50

100%的数据满足: n<=1000

如果满足 i<j<k &&num[i]<num[j],num[i]>num[k]就不能单栈排序并考虑双栈

  如果 不是二分图 就不能双栈排序

最后模拟输出  ————我居然在模拟上卡了很长时间!!

  1. #include <algorithm>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <queue>
  5.  
  6. using namespace std;
  7.  
  8. const int N(+);
  9. int n,num[N],pre,mi[N];
  10.  
  11. int head[N],sumedge;
  12. struct Edge
  13. {
  14. int u,v,next;
  15. Edge(int u=,int v=,int next=):
  16. u(u),v(v),next(next){}
  17. }edge[N<<];
  18. void ins(int u,int v)
  19. {
  20. edge[++sumedge]=Edge(u,v,head[u]);
  21. head[u]=sumedge;
  22. }
  23.  
  24. int col[N],st1[N],st2[N],to1,to2;
  25. void Paint_(int s)
  26. {
  27. col[s]=;
  28. queue<int>que;
  29. que.push(s);
  30. while(!que.empty())
  31. {
  32. pre=que.front();que.pop();
  33. for(int i=head[pre];i;i=edge[i].next)
  34. {
  35. int to=edge[i].v;
  36. if(col[to]!=-)
  37. {
  38. if(col[to]==col[pre])
  39. {
  40. puts("");
  41. exit();
  42. }
  43. }
  44. else
  45. {
  46. col[to]=col[pre]^;
  47. que.push(to);
  48. }
  49. }
  50. }
  51. }
  52.  
  53. int main()
  54. {
  55. scanf("%d",&n);
  56. for(int i=;i<=n;i++)
  57. scanf("%d",num+i);
  58. mi[n+]=1e7;
  59. for(int i=n;i>=;i--)
  60. mi[i]=min(mi[i+],num[i]);
  61. for(int i=;i<n;i++)
  62. for(int j=i+;j<=n;j++)
  63. if(num[i]<num[j]&&num[i]>mi[j+])
  64. ins(i,j),ins(j,i);
  65. memset(col,-,sizeof(col));
  66. for(int i=;i<=n;i++)
  67. if(col[i]==-) Paint_(i);
  68. int now_min=;
  69. for(int i=;i<=n;i++)
  70. {
  71. if(col[i]==)
  72. {
  73. if(num[i]==now_min)
  74. {
  75. printf("a b "),now_min++;
  76. if(st1[to1]==num[i]) to1--;
  77. }
  78. else if(!to1||st1[to1]>num[i])
  79. st1[++to1]=num[i],printf("a ");
  80. for(;to1&&st1[to1]==now_min;)
  81. printf("b "),to1--,now_min++;
  82. }
  83. else
  84. {
  85. if(num[i]==now_min)
  86. {
  87. printf("c d "),now_min++;
  88. if(st1[to1]==num[i]) to1--;
  89. }
  90. else if(!to2||st2[to2]>num[i])
  91. st2[++to2]=num[i],printf("c ");
  92. for(;to2&&st2[to2]==now_min;)
  93. printf("d "),to2--,now_min++;
  94. }
  95. }
  96. for(;now_min<=n;now_min++)
  97. {
  98. for(;st1[to1]==now_min;to1--) printf("b ");
  99. for(;st2[to2]==now_min;to2--) printf("d ");
  100. }
  101. return ;
  102. }

洛谷——P1155 双栈排序的更多相关文章

  1. 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

    洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...

  2. [NOIP2008] 提高组 洛谷P1155 双栈排序

    题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...

  3. 洛谷P1155 双栈排序

    这题什么毒瘤......之前看一直没思路,然后心说写个暴搜看能有多少分,然后就A了??! 题意:给你一个n排列,求它们能不能通过双栈来完成排序.如果能输出最小字典序方案. [update]这里面加了一 ...

  4. 洛谷P1155 双栈排序(贪心)

    题意 题目链接 Sol 首先不难想到一种贪心策略:能弹则弹,优先放A 然后xjb写了写发现只有\(40\),原因是存在需要决策的情况 比如 \(A = {10}\) \(B = {8}\) 现在进来一 ...

  5. 洛谷P1155 双栈排序——思路题

    题目:https://www.luogu.org/problemnew/show/P1155 思路... 看博客:https://www.cnblogs.com/Narh/p/9213825.html ...

  6. 洛谷 P1155 双栈排序

    题面 解题思路 这道题乍一看还以为是个模拟..怒写一发30分(noip提高组t4有模拟吗?). 其实很好hack,如 10 10 2 8 1 7 9 3 4 5 6 按模拟的思路,应该是10入第一个栈 ...

  7. 洛谷$P1155$ 双栈排序 贪心+二分图匹配

    正解:贪心+二分图匹配 解题报告: 传送门$QwQ$ 跪了,,,我本来以为我$NOIp$做得差不多了,,,然后康了一眼发现没做多少啊其实$QAQ$ 然后来康题趴$QwQ$ 首先考虑如果只有一个栈的情况 ...

  8. P1155 双栈排序(二分图染色)

    P1155 双栈排序(二分图染色) 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一 ...

  9. P1155 双栈排序

    题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作aaa 如果输入序列不为空,将第一个元素压入栈S1​ 操作b 如果 ...

随机推荐

  1. C++友元(Friend)简介

    相对Java而言,友元是C++中特有的一种元素,再加上<C++ Primer>也并没有太具体的样例,所以刚接触这个概念的时候懵了非常久,即是自己总结一下,也希望能帮到大家,以下来讲讲友元的 ...

  2. Centos7+httpd+fastcgi+rails安装

    搭建的环境: centos7 Apache/2.4.6 fastcgi2.4.6 rails4 在安装fastcgi的时候遇到了问题: 问题: .... .. In file included fro ...

  3. redis作为缓存场景使用,内存耗尽时,突然出现大量的逐出,在这个逐出的过程中阻塞正常的读写请求,导致 redis 短时间不可用

    redis 突然大量逐出导致读写请求block   内容目录: 现象 背景 原因 解决方案 ref 现象 redis作为缓存场景使用,内存耗尽时,突然出现大量的逐出,在这个逐出的过程中阻塞正常的读写请 ...

  4. 86.express里面的app.configure作用

    以下摘自 express 3.0 的 文档 app.configure([env], callback) Conditionally invoke callback when env matches ...

  5. 43.$http

    转自:https://www.cnblogs.com/best/tag/Angular/ $http 是 AngularJS 中的一个核心服务,用于读取远程服务器的数据. 使用格式: // 简单的 G ...

  6. HD-ACM算法专攻系列(2)——Rightmost Digit

    题目描述: 源码: /**/ #include"iostream" using namespace std; int main() { int t, mod; long long ...

  7. iOS开发——捕获崩溃信息

    可通过注册NSUncaughtExceptionHandler捕获异常信息,将拿到的NSException细节写入Crash日志,精准的定位出错程序位置,有需要的,可直接将crash信息直接上传服务器 ...

  8. XAMPP添加多个站点之httpd-vhosts.conf 设置

    1.在xampp\apache\conf\httpd.conf设置路径DocumentRoot和Directory 必须与xampp\apache\conf\extra\httpd-vhosts.co ...

  9. OpenGL之抗锯齿 以及 线宽的设置

    转自原文 OpenGL之抗锯齿 以及 线宽的设置 抗锯齿 1.线的抗锯齿 glEnable(GL_LINE_SMOOTH); //启用 glHint(GL_LINE_SMOOTH,GL_NICEST) ...

  10. 找出BST里面与Target最接近的n个数

    http://www.cnblogs.com/jcliBlogger/p/4771342.html 这里给了两种解法,一种是利用C++的priority_queue,然后逐个node输入. 另一种是先 ...