【问题描述】

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. java中的static变量

    java中的static变量 例如 public static int num=0: num+=1;放在函数里面 调用一次变动一次.

  2. 【转】find命令

    Linux中find常见用法示例·find path -option [ -print ] [ -exec -ok command ] {} \;find命令的参数: pathname: find命令 ...

  3. python-appium练习编写脚本时遇到问题

    遇到问题: 1.安卓4.2及以下系统无法识别resource-id属性 只能用text属性识别 2.输入中文无法识别 脚本最顶部增加#coding=utf-8 3.对象无法识别resource-id属 ...

  4. 基于jQuery的web在线流程图设计器GooFlow

    简易的流程图设计控件,效果图: JavaScript源文件在GooFlow.js中,样式文件是GooFlow2.css.可以自定义样式. GooFlow_item类是每个项的样式属性. 但估计实现任务 ...

  5. 关于NopCommerce3.6版用户登录详解

    一.登录方式 Nop登录方式有两种(且只能选择一种方式登录):一种是用用户名登录,另一种是用户注册邮箱登录,这个在后台可配置: 第一种:用户名登录 后台配置路径在商城设置à设置管理à客户设置:使用用户 ...

  6. 在EXCEL中使用SQL查询

    Excel2007及以上版本才有这个功能,2003版本的要么路过学习一下.要么去升级下自己的版本. Microsoft query 用的是 access 语法 如:判断空 oracle ------- ...

  7. SQL 实现,如果存在就更新,如果不存在就添加

    alter proc proc_DataSummary as begin begin try begin tran --PV --统计的信息存入临时表 ), CreateDate, ) ), Crea ...

  8. 洛谷P2264 情书

    P2264 情书 88通过 971提交 题目提供者lin_toto 标签字符串 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 yyy快把题目改回来 噫 这题的题目好逗啊... 情书std ...

  9. 一个不简单的Procedure body例子

    create or replace package body CountBankData_20150617 is type cursorCommon is ref cursor; --游标类型 str ...

  10. Freebsd下压缩解压文件详解

    压缩篇: 把/usr/webgames目录下的文件打包.命名为bak.tar.gz 放到/usr/db-bak目录里 下面命令可以在任意目录执行.无视当前目录和将要存放文件的目录.tar -zcvf ...