题目描述

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;否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。

看到这道题,首先就打了个30分的错误代码 然后又是一个30分的超时,紧接着还是30分。这道题是一道不错的题,是关于二分图的(其实看了题解很久才明白)

题解中说的很详细,但是染色的过程是比较纠结的。其实是挺有技巧的。

代码上半部分是我的龟速染色,下面才是正确的染色方法。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <stack>
  5. #define INF 2000100
  6. using namespace std;
  7. int map[][]; //0可以 1不可以
  8. int num[],dp[];
  9. int col[]={};
  10. int n;
  11. int min(int a,int b)
  12. {
  13. return a>b?b:a;
  14. }
  15. stack<int> s1;
  16. stack<int> s2;
  17. int main()
  18. {
  19. scanf("%d",&n);
  20. for(int i=;i<=n;++i)scanf("%d",&num[i]);
  21. num[n+]=INF;dp[n+]=INF;
  22. for (int i=n;i>=;--i) dp[i]=min(dp[i+],num[i]);
  23. for (int i=;i<n;++i)
  24. for (int j=i+;j<=n;++j)
  25. if (num[i]<num[j]&&num[i]>dp[j+])
  26. map[i][j]=map[j][i]=;
  27. for (int i=;i<=n;++i){
  28. if (col[i]==){
  29. col[i]=;
  30. for (int j=i+;j<=n;j++){
  31. if (map[i][j]&&col[j]==){
  32. cout<<""<<endl;
  33. return ;
  34. }
  35. else if (map[i][j]) col[j]=;
  36. }
  37. }
  38. if (col[i]==){
  39. for (int j=i+;j<=n;j++){
  40. if (map[i][j]&&col[j]==){
  41. cout<<""<<endl;
  42. return ;
  43. }
  44. }
  45. }
  46. }
  47. int aim=;
  48. for (int i=;i<=n;i++){
  49. if (col[i]==){
  50. cout<<"a ";
  51. s1.push(num[i]);
  52. }
  53. if (col[i]==){
  54. cout<<"c ";
  55. s2.push(num[i]);
  56. }
  57. while (!s1.empty()){
  58. if (s1.top()==aim){
  59. aim++;
  60. cout<<"b ";
  61. s1.pop();
  62. }
  63. else break;
  64. }
  65. while (!s2.empty()){
  66. if (s2.top()==aim){
  67. aim++;
  68. cout<<"d ";
  69. s2.pop();
  70. }
  71. else break;
  72. }
  73. }
  74. while (!s1.empty()||!s2.empty())
  75. {
  76. while (!s1.empty()){
  77. if (s1.top()==aim){
  78. aim++;
  79. cout<<"b ";
  80. s1.pop();
  81. }
  82. else break;
  83. }
  84. while (!s2.empty()){
  85. if (s2.top()==aim){
  86. aim++;
  87. cout<<"d ";
  88. s2.pop();
  89. }
  90. else break;
  91. }
  92. }
  93. cout<<endl;
  94. }
  95.  
  96. #include <cstdio>
  97. #include <cstring>
  98. #include <iostream>
  99. #include <stack>
  100. #include <cstdlib>
  101. #define INF 2000100
  102. using namespace std;
  103. int map[][]; //0可以 1不可以
  104. int num[],dp[];
  105. int col[]={};
  106. int n;
  107. int min(int a,int b)
  108. {
  109. return a>b?b:a;
  110. }
  111. void dfs(int x, int c)
  112. {
  113. col[x] = c;
  114. for (int i=;i<=n;++i)
  115. if (map[x][i])
  116. {
  117. if (col[i]==c){
  118. cout<<""<<endl;
  119. exit();
  120. }
  121. if (!col[i])
  122. dfs(i, -c);
  123. }
  124. }
  125.  
  126. stack<int> s1;
  127. stack<int> s2;
  128. int main()
  129. {
  130. scanf("%d",&n);
  131. for(int i=;i<=n;++i)scanf("%d",&num[i]);
  132. num[n+]=INF;dp[n+]=INF;
  133. for (int i=n;i>=;--i) dp[i]=min(dp[i+],num[i]);
  134. for (int i=;i<n;++i)
  135. for (int j=i+;j<=n;++j)
  136. if (num[i]<num[j]&&num[i]>dp[j+])
  137. map[i][j]=map[j][i]=;
  138. for (int i = ; i <= n;++i)
  139. if (!col[i]) dfs(i,);
  140. int aim=;
  141. for (int i=;i<=n;i++){
  142. if (col[i]==){
  143. cout<<"a ";
  144. s1.push(num[i]);
  145. }
  146. else {
  147. cout<<"c ";
  148. s2.push(num[i]);
  149. }
  150. while (!s1.empty()){
  151. if (s1.top()==aim){
  152. aim++;
  153. cout<<"b ";
  154. s1.pop();
  155. }
  156. else break;
  157. }
  158. while (!s2.empty()){
  159. if (s2.top()==aim){
  160. aim++;
  161. cout<<"d ";
  162. s2.pop();
  163. }
  164. else break;
  165. }
  166. }
  167. while (!s1.empty()||!s2.empty())
  168. {
  169. while (!s1.empty()){
  170. if (s1.top()==aim){
  171. aim++;
  172. cout<<"b ";
  173. s1.pop();
  174. }
  175. else break;
  176. }
  177. while (!s2.empty()){
  178. if (s2.top()==aim){
  179. aim++;
  180. cout<<"d ";
  181. s2.pop();
  182. }
  183. else break;
  184. }
  185. }
  186. cout<<endl;
  187. }

大概就是这样了。

#include <NOIP2008 Junior> 双栈排序 ——using namespace wxl;的更多相关文章

  1. #include &lt;NOIP2008 Junior&gt; 双栈排序 ——using namespace wxl;

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

  2. 【NOIP2008】双栈排序

    感觉看了题解还是挺简单的,不知道当年chty同学为什么被卡了呢么久--所以说我还是看题解了 原题: Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将 ...

  3. 【提高组NOIP2008】双栈排序 (twostack.pas/c/cpp)

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

  4. 洛谷 P1155 【NOIP2008】双栈排序

    题目链接 题解 这题有点神啊.. 我们仔细观察一下,发现两个栈内元素必须为降序 那么有结论 如果有\(i < j < k\) 且 \(a[k] < a[i] < a[j]\)则 ...

  5. LG1155 「NOIP2008」双栈排序 二分图判定

    问题描述 LG1155 题解 \(i,j\)如果不能进入一个栈,要满足存在\(k\),使得\(i<j<k\)且\(a_k<a_i<a_j\) 如果\(i,j\)不能进入一个栈, ...

  6. Luogu1155 NOIP2008 双栈排序 【二分图染色】【模拟】

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

  7. NOIP2008双栈排序[二分图染色|栈|DP]

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

  8. noip2008 双栈排序

    题目描述 Description \(Tom\)最近在研究一个有趣的排序问题.如图所示,通过\(2\)个栈\(S_1\)和\(S_2\),\(Tom\)希望借助以下\(4\)种操作实现将输入序列升序排 ...

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

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

随机推荐

  1. OAuth2.0 基础概述

    web:http://oauth.net/2/ rfc:http://tools.ietf.org/html/rfc6749 doc:http://oauth.net/documentation/ c ...

  2. treap树---营业额统计

    台州学院  2924 描述 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况.Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额 ...

  3. HDU 1028(母函数)

    Online Judge Online Exercise Online Teaching Online Contests Exercise Author F.A.QHand In HandOnline ...

  4. SQL Server 全局变量

    SQL Server中所有全局变量都使用两个@符号作为前缀 --1.@@error 最后一个T-SQL错误的错误号(目的是或得违反约束的错误号) insert into Subject values( ...

  5. Linux下的crontab命令使用特别须注意的地方

    1.如果命令中涉及到了年月日(如:date +%C%y%m%d),其中%必须进行转义,如下: date +\%C\%y\%m\%d 2.使用到的命令必须使用完整的路径: * * * /home/yxf ...

  6. uml入门之14图与图之间的关系

    1.先奉上整理的14图. 2.其次奉上整理的图之间的6种关系

  7. 文科生也能看懂的iptables教程(转载)

    据说还是个MM, 写得很通俗易懂, 还很诙谐, 原文:http://dallascao.com/cn/iptables-tutorial-for-newbies/ 对于斗胆开始玩vps的文科生来讲,i ...

  8. ASP.NET HttpRuntime.Cache缓存类使用总结

    1.高性能文件缓存key-value存储—Redis 2.高性能文件缓存key-value存储—Memcached 备注:三篇博文结合阅读,简单理解并且使用,如果想深入学习,请多参考文章中给出的博文地 ...

  9. 安卓开发-问题集-Description Resource Path Location TypeUnparsed aapt error(s)! Check the console for output.

    今天在安卓项目中 res-drawable-hdpi 替换图片的时候出现这个问题 问题现象为项目显示一个叉号,但是在项目内容的任何文件都不显示叉号, 搞了半天没发现是什么问题,然后就去项目的文件夹下 ...

  10. IOS 杂笔-5(NSTimer极浅析)

    1.timer都会对它的target进行retain,我们需要小心对待这个target的生命周期问题,尤其是重复性的timer. 2. timer不是一种实时的机制,会存在延迟,而且延迟的程度跟当前线 ...