题目描述

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 &lt;NOIP2008 Junior&gt; 双栈排序 ——using namespace wxl;的更多相关文章

  1. #include <NOIP2008 Junior> 双栈排序 ——using namespace wxl;

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

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

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

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

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

  4. noip2008 双栈排序

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

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

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

  6. 【NOIP2008】双栈排序

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

  7. Noip2008双栈排序

    [问题描述] 用两个栈使一个1...n的排列变得有序.一共有四个操作: A.stack1.push() 读入一个放入栈一 B.stack1.pop() 弹出栈一放入输出序列 C.stack2.push ...

  8. NOIP2008双栈排序(贪心)

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

  9. [题解] [NOIP2008] 双栈排序——关系的冲突至图论解法

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

随机推荐

  1. 0ra-12170 tns 连接超时

    https://blog.csdn.net/zhaoxiangchong/article/details/8296980

  2. 语音性别识别 - 使用R提取特征

    步骤 1)安装R.windows操作系统安装包的链接:https://cran.r-project.org/bin/windows/base/ 2)切换当前路径为脚本所在路径 点击 文件 > 改 ...

  3. java EE : tomacat 基础

    tomacat 目录结构 conf 配置文件  server.xml

  4. (15) go 方法

  5. SQL必知必会 -------- order by、where等

    一.排序检索数据 1.排序数据:SELECT prod_name FROM Products ORDER BY prod_name(对prod_name列以字母顺序排序数据) ORDER BY子句的位 ...

  6. CodeForces 909E Coprocessor

    题解. 贪心,拓扑排序. 和拓扑排序一样,先把$flag$为$0$的点能删的都删光,露出来的肯定都是$flag$为$0$的,然后疯狂删$flag$为$0$的,这些会使答案加$1$,反复操作就可以了. ...

  7. 洛谷P3857 [TJOI2008]彩灯 [线性基]

    题目传送门 彩灯 题目描述 Peter女朋友的生日快到了,他亲自设计了一组彩灯,想给女朋友一个惊喜.已知一组彩灯是由一排N个独立的灯泡构成的,并且有M个开关控制它们.从数学的角度看,这一排彩灯的任何一 ...

  8. c++ getline()

    #include <iostream>#include <string> int main (){ std::string name; std::cout << & ...

  9. 【BZOJ 4455】 4455: [Zjoi2016]小星星 (容斥原理+树形DP)

    4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 426  Solved: 255 Description 小Y是 ...

  10. 安卓 Activity Fragment 生命周期

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 活动:  创建->启动->获得焦点->暂停->停止->销毁 ...