#include <NOIP2008 Junior> 双栈排序 ——using namespace wxl;
题目描述
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[][]; //0可以 1不可以
- int num[],dp[];
- int col[]={};
- 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=;i<=n;++i)scanf("%d",&num[i]);
- num[n+]=INF;dp[n+]=INF;
- for (int i=n;i>=;--i) dp[i]=min(dp[i+],num[i]);
- for (int i=;i<n;++i)
- for (int j=i+;j<=n;++j)
- if (num[i]<num[j]&&num[i]>dp[j+])
- map[i][j]=map[j][i]=;
- for (int i=;i<=n;++i){
- if (col[i]==){
- col[i]=;
- for (int j=i+;j<=n;j++){
- if (map[i][j]&&col[j]==){
- cout<<""<<endl;
- return ;
- }
- else if (map[i][j]) col[j]=;
- }
- }
- if (col[i]==){
- for (int j=i+;j<=n;j++){
- if (map[i][j]&&col[j]==){
- cout<<""<<endl;
- return ;
- }
- }
- }
- }
- int aim=;
- for (int i=;i<=n;i++){
- if (col[i]==){
- cout<<"a ";
- s1.push(num[i]);
- }
- if (col[i]==){
- 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[][]; //0可以 1不可以
- int num[],dp[];
- int col[]={};
- 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=;i<=n;++i)
- if (map[x][i])
- {
- if (col[i]==c){
- cout<<""<<endl;
- exit();
- }
- if (!col[i])
- dfs(i, -c);
- }
- }
- stack<int> s1;
- stack<int> s2;
- int main()
- {
- scanf("%d",&n);
- for(int i=;i<=n;++i)scanf("%d",&num[i]);
- num[n+]=INF;dp[n+]=INF;
- for (int i=n;i>=;--i) dp[i]=min(dp[i+],num[i]);
- for (int i=;i<n;++i)
- for (int j=i+;j<=n;++j)
- if (num[i]<num[j]&&num[i]>dp[j+])
- map[i][j]=map[j][i]=;
- for (int i = ; i <= n;++i)
- if (!col[i]) dfs(i,);
- int aim=;
- for (int i=;i<=n;i++){
- if (col[i]==){
- 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;
- }
大概就是这样了。
#include <NOIP2008 Junior> 双栈排序 ——using namespace wxl;的更多相关文章
- #include <NOIP2008 Junior> 双栈排序 ——using namespace wxl;
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- Luogu1155 NOIP2008 双栈排序 【二分图染色】【模拟】
Luogu1155 NOIP2008 双栈排序 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过 2个栈 S1 和 S2 ,Tom希望借助以下 44 种操作实现将输入序列升序排序. 操作 ...
- NOIP2008双栈排序[二分图染色|栈|DP]
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- noip2008 双栈排序
题目描述 Description \(Tom\)最近在研究一个有趣的排序问题.如图所示,通过\(2\)个栈\(S_1\)和\(S_2\),\(Tom\)希望借助以下\(4\)种操作实现将输入序列升序排 ...
- [NOIP2008] 提高组 洛谷P1155 双栈排序
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- 【NOIP2008】双栈排序
感觉看了题解还是挺简单的,不知道当年chty同学为什么被卡了呢么久--所以说我还是看题解了 原题: Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将 ...
- Noip2008双栈排序
[问题描述] 用两个栈使一个1...n的排列变得有序.一共有四个操作: A.stack1.push() 读入一个放入栈一 B.stack1.pop() 弹出栈一放入输出序列 C.stack2.push ...
- NOIP2008双栈排序(贪心)
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- [题解] [NOIP2008] 双栈排序——关系的冲突至图论解法
Problem 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操 ...
随机推荐
- 0ra-12170 tns 连接超时
https://blog.csdn.net/zhaoxiangchong/article/details/8296980
- 语音性别识别 - 使用R提取特征
步骤 1)安装R.windows操作系统安装包的链接:https://cran.r-project.org/bin/windows/base/ 2)切换当前路径为脚本所在路径 点击 文件 > 改 ...
- java EE : tomacat 基础
tomacat 目录结构 conf 配置文件 server.xml
- (15) go 方法
- SQL必知必会 -------- order by、where等
一.排序检索数据 1.排序数据:SELECT prod_name FROM Products ORDER BY prod_name(对prod_name列以字母顺序排序数据) ORDER BY子句的位 ...
- CodeForces 909E Coprocessor
题解. 贪心,拓扑排序. 和拓扑排序一样,先把$flag$为$0$的点能删的都删光,露出来的肯定都是$flag$为$0$的,然后疯狂删$flag$为$0$的,这些会使答案加$1$,反复操作就可以了. ...
- 洛谷P3857 [TJOI2008]彩灯 [线性基]
题目传送门 彩灯 题目描述 Peter女朋友的生日快到了,他亲自设计了一组彩灯,想给女朋友一个惊喜.已知一组彩灯是由一排N个独立的灯泡构成的,并且有M个开关控制它们.从数学的角度看,这一排彩灯的任何一 ...
- c++ getline()
#include <iostream>#include <string> int main (){ std::string name; std::cout << & ...
- 【BZOJ 4455】 4455: [Zjoi2016]小星星 (容斥原理+树形DP)
4455: [Zjoi2016]小星星 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 426 Solved: 255 Description 小Y是 ...
- 安卓 Activity Fragment 生命周期
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 活动: 创建->启动->获得焦点->暂停->停止->销毁 ...