题目描述

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分。这道题是一道不错的题,是关于二分图的(其实看了题解很久才明白)

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

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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>
#define INF 2000100
using namespace std;
int map[1001][1001]; //0可以 1不可以
int num[1002],dp[1002];
int col[1002]={0};
int n;
int min(int a,int b)
{return a>b?b:a;
}
stack<int> s1;
stack<int> s2;
int main()
{scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%d",&num[i]);num[n+1]=INF;dp[n+1]=INF;for (int i=n;i>=1;--i) dp[i]=min(dp[i+1],num[i]);for (int i=1;i<n;++i)for (int j=i+1;j<=n;++j)if (num[i]<num[j]&&num[i]>dp[j+1])map[i][j]=map[j][i]=1;for (int i=1;i<=n;++i){if (col[i]==0){col[i]=1;for (int j=i+1;j<=n;j++){if (map[i][j]&&col[j]==1){cout<<"0"<<endl;return 0;}else if (map[i][j]) col[j]=2;}}if (col[i]==2){for (int j=i+1;j<=n;j++){if (map[i][j]&&col[j]==2){cout<<"0"<<endl;return 0;} }}}int aim=1;for (int i=1;i<=n;i++){if (col[i]==1){cout<<"a ";s1.push(num[i]);}if (col[i]==2){cout<<"c ";s2.push(num[i]);}while (!s1.empty()){if (s1.top()==aim){aim++;cout<<"b ";s1.pop();}else break;}while (!s2.empty()){if (s2.top()==aim){aim++;cout<<"d ";s2.pop();}else break;}}while (!s1.empty()||!s2.empty()){    while (!s1.empty()){if (s1.top()==aim){aim++;cout<<"b ";s1.pop();}else break;}while (!s2.empty()){if (s2.top()==aim){aim++;cout<<"d ";s2.pop();}else break;}}cout<<endl;
}#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>
#include <cstdlib>
#define INF 2000100
using namespace std;
int map[1001][1001]; //0可以 1不可以
int num[1002],dp[1002];
int col[1002]={0};
int n;
int min(int a,int b)
{return a>b?b:a;
}
void  dfs(int x, int c)
{col[x] = c;for (int i=1;i<=n;++i)if (map[x][i]){if (col[i]==c){cout<<"0"<<endl;exit(0);}if (!col[i])dfs(i, 3-c);}
}stack<int> s1;
stack<int> s2;
int main()
{scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%d",&num[i]);num[n+1]=INF;dp[n+1]=INF;for (int i=n;i>=1;--i) dp[i]=min(dp[i+1],num[i]);for (int i=1;i<n;++i)for (int j=i+1;j<=n;++j)if (num[i]<num[j]&&num[i]>dp[j+1])map[i][j]=map[j][i]=1;for (int i = 1; i <= n;++i)  if (!col[i]) dfs(i,1);int aim=1;for (int i=1;i<=n;i++){if (col[i]==1){cout<<"a ";s1.push(num[i]);}else {cout<<"c ";s2.push(num[i]);}while (!s1.empty()){if (s1.top()==aim){aim++;cout<<"b ";s1.pop();}else break;}while (!s2.empty()){if (s2.top()==aim){aim++;cout<<"d ";s2.pop();}else break;}}while (!s1.empty()||!s2.empty()){    while (!s1.empty()){if (s1.top()==aim){aim++;cout<<"b ";s1.pop();}else break;}while (!s2.empty()){if (s2.top()==aim){aim++;cout<<"d ";s2.pop();}else break;}}cout<<endl;
}

大概就是这样了。

转载于:https://www.cnblogs.com/AwesomeOrion/p/5428834.html

#include NOIP2008 Junior 双栈排序 ——using namespace wxl;相关推荐

  1. #include lt;NOIP2008 Juniorgt; 双栈排序 ——using namespace wxl;

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

  2. NOIP2008 双栈排序

    https://www.luogu.org/problem/show?pid=1155 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输 ...

  3. P1155 双栈排序(二分图的染色判断+链式前向星)

    P1155 双栈排序 让字典序最小,当然尽量进S1 那什么时候必须进S2呢? a[i]和a[j] 不能压入同一个栈⇔存在一个k,使得i<j<k且a[k]<a[i]<a[j] 因 ...

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

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

  5. AC日记——双栈排序 洛谷 P1155

    双栈排序 思路: 二分图染+模拟: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 #define ...

  6. 【每日一题】8月7日题目精讲—双栈排序

    来源:牛客网 文章目录 题目描述 题意: 题解: 代码: 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言262144K 64bit IO Format: %l ...

  7. [大牛就是牛]双栈排序

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

  8. P1155 双栈排序

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

  9. 洛谷——P1155 双栈排序

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

最新文章

  1. 区块链】利用Node.js开发与合约交互的Web界面
  2. linux线程同步(5)-屏障
  3. axios打包放到服务器上接口地址404_如何把网页文件放到云虚拟主机
  4. Linux 查看 MySQL 版本的四种方法
  5. 微服务内部方法调用方式
  6. typedef struct引起的结构体问题
  7. Nature Neuroscience(一)
  8. MAX30102+usb转串口+树莓派
  9. 劳动与社会保障法-作业
  10. 关于课题的一点思考(基于多生理信号的情绪识别)
  11. 跟我学Spring3-开涛-笔记
  12. 威联通 php升级,威联通折腾篇十七:Docker 安装的 NextCloud 升级、备份及恢复
  13. JAVA常见面试题及解答
  14. 阿里云服务器包年包月/按量计费/抢占式实例模式选择方法
  15. 工作流系统之四十 抄送功能的实现
  16. Windows API一日一练 29 SelectObject和DeleteObject函数
  17. HttpClient Get请求带参数
  18. 【aabb 7744】
  19. vue中实现Excel导入导出功能
  20. java计算工作日方法

热门文章

  1. 下列哪个不属于计算机的应用范围,、下列哪个选项不 属于计算机的应用软件。...
  2. UVa Problem 10254 The Priest Mathematician (牧师数学家)
  3. 【Lawin Transformer2022】Lawin Transformer: Improving Semantic Segmentation Transformer with Multi-Sc
  4. Python调用百度地图api路径查询
  5. 10办公软件软件分享
  6. 如何用Go实现一款类似滴滴优步的网络约车软件(含源码)
  7. 人体经络气血运行规律
  8. 百度地图这十年如何一步步干掉了强悍的对手?
  9. 区块链:Casper 机制的历史起源:第一篇
  10. 一个java游戏有各种天书三国,机号申请的网络游戏,天书九卷,这游戏是免 的,里...