[NOIP2008] 提高组 洛谷P1155 双栈排序
题目描述
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】
4
1 3 2 4
【输入样例2】
4
2 3 4 1
【输入样例3】
3
2 3 1
【输出样例1】
a b a a b b a b
【输出样例2】
0
【输出样例3】
a c a b b d
说明
30%的数据满足: n<=10
50%的数据满足: n<=50
100%的数据满足: n<=1000
考虑单栈排序:如果有三个元素a[i]<a[j] && a[i]>a[k],且它们的顺序 i<j<k,a[i]出栈以后a[j]才能进栈,a[k]出栈以后a[i]才能出栈,显然无法满足要求。
所以,如果三个数满足以上条件,它们是不能同进一个栈的。
先n downto 1倒推出每个数后面最小的数,作为a[k],然后枚举a[i],a[j],若符合上述条件,则在i,j之间连边,表示它们不能进同一个栈。
之后进行二分图染色,如果遇到颜色矛盾,说明不能把冲突的点对分成两组,也就是问题无解。
如果没有冲突,则问题有解,模拟即可。
/*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<stack>
using namespace std;
const int mxn=;
struct edge{
int v;
int nxt;
}e[mxn];
int hd[mxn],mct=;
void add_edge(int u,int v){
e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;
return;
}
int a[mxn],n;
int mini[mxn];
int c[mxn];
int ans[mxn],t=;
bool dfs(int u){
if(c[u]==-)c[u]=;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(c[v]==-){
c[v]=c[u]^;
if(!dfs(v))return ;
}
else{
if(c[v]==c[u])return ;
}
}
return ;
}
stack<int>tp1,tp2;
int main(){
memset(c,-,sizeof c);
int i,j;
scanf("%d",&n);
mini[n+]=0x3f3f3f;
for(i=;i<=n;i++)scanf("%d",&a[i]);
for(i=n;i;i--) mini[i]=min(mini[i+],a[i]);
for(i=;i<n;i++)
for(j=i+;j<=n;j++){
if(a[i]<a[j] && a[i]>mini[j+]){
add_edge(j,i);
add_edge(i,j);
}
}
for(i=;i<=n;i++)
if(c[i]==-){
if(!dfs(i)){
printf("0\n");
return ;
}
}
int now=;
i=;
while(){
if(now>n)break;
if(c[i]== && (tp1.empty() || tp1.top()>a[i])){
tp1.push(a[i]);
ans[++t]=;
i++;
continue;
}
if(!tp1.empty() && tp1.top()==now){
ans[++t]=;
tp1.pop();
now++;
continue;
}
if(c[i]== && (tp2.empty() || tp2.top()>a[i])){
tp2.push(a[i]);
ans[++t]=;
i++;
continue;
}
if(!tp2.empty() && tp2.top()==now){
tp2.pop();
ans[++t]=;
now++;
continue;
}
}
for(i=;i<=t;i++)printf("%c ",(char)ans[i]+'a'-);
printf("\n");
return ;
}
[NOIP2008] 提高组 洛谷P1155 双栈排序的更多相关文章
- 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)
洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...
- 洛谷——P1155 双栈排序
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- 洛谷P1155 双栈排序
这题什么毒瘤......之前看一直没思路,然后心说写个暴搜看能有多少分,然后就A了??! 题意:给你一个n排列,求它们能不能通过双栈来完成排序.如果能输出最小字典序方案. [update]这里面加了一 ...
- 洛谷 P1155 双栈排序
题面 解题思路 这道题乍一看还以为是个模拟..怒写一发30分(noip提高组t4有模拟吗?). 其实很好hack,如 10 10 2 8 1 7 9 3 4 5 6 按模拟的思路,应该是10入第一个栈 ...
- 洛谷P1155 双栈排序(贪心)
题意 题目链接 Sol 首先不难想到一种贪心策略:能弹则弹,优先放A 然后xjb写了写发现只有\(40\),原因是存在需要决策的情况 比如 \(A = {10}\) \(B = {8}\) 现在进来一 ...
- 洛谷P1155 双栈排序——思路题
题目:https://www.luogu.org/problemnew/show/P1155 思路... 看博客:https://www.cnblogs.com/Narh/p/9213825.html ...
- 洛谷$P1155$ 双栈排序 贪心+二分图匹配
正解:贪心+二分图匹配 解题报告: 传送门$QwQ$ 跪了,,,我本来以为我$NOIp$做得差不多了,,,然后康了一眼发现没做多少啊其实$QAQ$ 然后来康题趴$QwQ$ 首先考虑如果只有一个栈的情况 ...
- [NOIP2008] 提高组 洛谷P1006 传纸条
题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是 ...
- [NOIP2008] 提高组 洛谷P1125 笨小猴
题目描述 笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼.但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大! 这种方法的具体描述如下:假设maxn是单词中出现次数最 ...
随机推荐
- cookie 、session、JSESSIONID
cookie .session ? 让我们用几个例子来描述一下cookie和session机制之间的区别与联系.笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微 ...
- [转]服务器自动化操作 RunDeck
From : http://www.oschina.net/p/rundeck/similar_projects?sort=view&lang=25 RunDeck 是用 Java/Grail ...
- 装了个干净的win7
lanny的电脑基本信息 我的电脑 联想 ThinkPad T450s 笔记本电脑 操作系统 Windows 旗舰版 64位 主显卡 集成显卡 IE浏览器 版本号 8.0 基本硬件展示 处理器 英特尔 ...
- android ContentResolver详解
查询出来的cursor的初始位置是指向第一条记录的前一个位置的cursor.moveToFirst()指向查询结果的第一个位置.一般通过判断cursor.moveToFirst()的值为true或fa ...
- C语言 百炼成钢11
//题目31:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续 //判断第二个字母. #define _CRT_SECURE_NO_WARNINGS #include<st ...
- [iOS翻译]Cocoa编码规范
简介: 本文整理自Apple文档<Coding Guidelines for Cocoa>.这份文档原意是给Cocoa框架.插件及公共API开发者提供一些编码指导,实质上相当于Ap ...
- 使用ObjectAnimator设置动画
ObjectAnimator是ValueAnimator的子类,他本身就已经包含了时间引擎和值计算,所以它拥有为对象的某个属性设置动画的功能.这使得为任何对象设置动画更加的容易.你不再需要实现 Val ...
- Android:支持多选的本地相册
前段时间在做一个动态发布功能,需要用到图片上传.一开始直接调用的系统相册和相机,由于系统相机不支持多选,就花点时间做了个本地相册,在此开源下. 先上截图,依次为选择相册界面.相册详情界面.查看图片大图 ...
- <转载> 你应该更新的Java知识之常用程序库(一)
原文出处:http://www.blogbus.com/dreamhead-logs/226738702.html 很多人眼中,Java已经是一门垂垂老矣的语言,但并不妨碍Java世界依然在前进.如果 ...
- 20135202闫佳歆--week 9 期中总结
期中总结 前半学期的主要学习内容是学习mooc课程<Linux内核分析>以及课本<Linux内核设计与实现>. 所涉及知识点总结如下: 1. Linux内核启动的过程--以Me ...