【问题描述】

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希望知道其中字典序最小的操作序列是什么。

【样例输入1】

4

1 3 2 4

【样例输出1】

a b a a b b a b

【样例输入2】

4

2 3 4 1

【样例输出2】

0

【样例输入3】

3

2 3 1

【样例输出3】

a c a b b d

【解题思路】

本题为NOIP2008提高组第四题,初看觉得这应该是有史以来最水的提高组最后一题了,这不是模拟吗?只不过模拟的东西多了一点而已,然而,当我写着写着,就发现模拟的有点不对劲了……

好吧,这道题的正解应该是图的染色+模拟……

是的,没错,你没有看错,第四题居然要模拟!!!

染色其实是一个深搜的过程,染色是为了区分程序从头到尾始终不能放在一个栈中的数,然后为了保证是字典序最小,因此尽量往栈1中放,如果有始终无法放到同一个栈中的数被放到了同一个栈(这里的被放到同一个栈是指的染成同一种颜色),那么就无解,输出0。(染色的方法可以百度floodfill或者种子染色法)

那么问题来了……挖掘机哪家……不对……怎么区分始终不能放在一个栈中的数呢?

如果存在k使得i<j<k且ak<ai<aj则ai和aj不能进入同一个栈。

我们可以手推一下,如果k>j>i说明,j在i的后面进栈,k在j的后面进栈,而此时ai<aj,那么如果ai和aj进了同一个栈,那么就会是aj先出栈,就肯定不是从小到大排好序的了。

染完色后就好办了,直接模拟进栈出栈的过程……如果是最小值,就出,否则就进,然后因为已经染了色了,根据染的色判断它是进(出)栈1还是栈2,然后输出相应的字符即可。

现在还有一个最最担心的问题,怎么确定这个数是不是当前需要出栈的数(即最小值)?好吧……其实是我眼睛瞎了,是的,我为此纠结了半天,然后看题目……一个1~n的排列P……直接最小值赋值为1,然后出栈了就Inc……

【代码实现】

 uses math;
var flag:array[..,..] of boolean;
q1,q2,color,a,f:array[..] of longint;
n,i,j,sum,t1,t2:longint;
procedure dfs(x,c:longint);
var i:longint;
begin
color[x]:=c;
for i:= to n do
if flag[x,i] then
begin
if color[i]=c then
begin
writeln();
halt;
end;
if color[i]= then
dfs(i,-c);
end;
end;
begin
readln(n);
for i:= to n do
read(a[i]);
f[n+]:=maxlongint;
for i:=n downto do
f[i]:=min(a[i],f[i+]);
for i:= to n- do
for j:=i+ to n do
if (a[i]<a[j])and(f[j+]<a[i]) then
begin
flag[i,j]:=true;
flag[j,i]:=true;
end;//初始化,哪些是始终无法进同一个栈的
for i:= to n do
if color[i]= then
dfs(i,);//给每一个数染色
sum:=;
for i:= to n do
begin
if color[i]= then
begin
inc(t1);
q1[t1]:=a[i];
write('a ');
end
else
begin
inc(t2);
q2[t2]:=a[i];
write('c ');
end;
while ((t1<>)and(q1[t1]=sum))or((t2<>)and(q2[t2]=sum)) do
begin
if (<>t1)and(q1[t1]=sum) then
begin
dec(t1);
write('b ');
end
else
begin
dec(t2);
write('d ');
end;
inc(sum);//最小值
end;
end;//最恶心的模拟……
end.

双栈排序(codevs 1170)题解的更多相关文章

  1. 双栈排序(codevs 1170)

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

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

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

  3. 虚拟化构建二分图(BZOJ2080 题解+浅谈几道双栈排序思想的题)

    虚拟化构建二分图 ------BZOJ2080 题解+浅谈几道双栈排序思想的题 本题的题解在最下面↓↓↓ 不得不说,第一次接触类似于双栈排序的这种题,是在BZOJ的五月月赛上. [BZOJ4881][ ...

  4. 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

    洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...

  5. noip2008 双栈排序

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

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

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

  7. 【NOIP2008】双栈排序

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

  8. Noip2008双栈排序

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

  9. 二分图 and code1170 双栈排序

    6.6二分图 二分图是这样一个图: 有两顶点集且图中每条边的的两个顶点分别位于两个顶点集中,每个顶点集中没有边直接相连接. 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶 ...

随机推荐

  1. 查看用户的SQL执行历史

    程序开发少不来SQL,基本都是基于SQL开发,程序仅仅起一个流程控制的作用.但是数据库本身存在许多内置的视图或者内置的表,如果打算研究SQL执行的效率已经SQL执行的历史记录,通过这些视图可以知道. ...

  2. 编码中常用的SQL语法

    蓝色标注的都是比较常见的SQL ====================== 开发中常见的SQL: left join , right join 防止丢弃数据 inner join CASE WHNE ...

  3. Oracle GoldenGate 11.2 OGG-01168(转)

    为客户部署的Oracle GoldenGate在测试阶段出现如下的错误: 2012-04-24 10:45:20  ERROR   OGG-01168  Oracle GoldenGate Deliv ...

  4. python3 pickle, json

    pickle 有dump ,dumps ,load,loads等方法.区别在于dumps不会写入到文件. import pickle string = ['a', 2341, 'adsf'] p_st ...

  5. locals()函数访问当前还在作用范围内的局部变量

    >>> element = 'silver' >>> number = 47 >>> 'Element {number} is {element} ...

  6. 项目积累——jQuery

    初始化时为文本框赋值,聚焦后清空内容 $(function(){ $("#buyDate").val("格式:2014-01-01"); $("#bu ...

  7. 【翻译】使用CSS3和jQuery制作跟随鼠标方位的Hover特效

    今天我们来学习如何通过CSS3的特性和jQuery来创建一个感知鼠标滑动方向的hover效果.当鼠标滑进的时候,遮罩层会从上次鼠标滑出的方向滑入,当鼠标滑出的时候,遮罩层会跟随鼠标,从鼠标滑出的方向滑 ...

  8. 慕课网-安卓工程师初养成-4-3 Java条件语句之多重 if

    来源:http://www.imooc.com/code/1355 多重 if 语句,在条件 1 不满足的情况下,才会进行条件 2 的判断:当前面的条件均不成立时,才会执行 else 块内的代码.例如 ...

  9. redis(二)Redis适用场景,如何正确的使用

    网络IO模型 Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe 传递给worker线程,进行读写IO, ...

  10. android大项目运行中出现问题汇总

    Android 项目中,特别是当项目文件和规模达到一定的程度后,会引发一些平常不常见的问题. 下面对遇到的一些问题做一个汇总和总结. scenario 1: 在项目中,我们采用了chromimum内核 ...