双栈排序

2008年NOIP全国联赛提高组

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 大师 Master
 
 
题目描述 Description

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

输入描述 Input Description

输入的第一行是一个整数n。

第二行有n个用空格隔开的正整数,构成一个1~n的排列。

输出描述 Output Description

输出共一行,如果输入的排列不是“可双栈排序排列”,输出数字0;否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。

样例输入 Sample Input

【样例1】

4

1 3 2 4

【样例2】

4

2 3 4 1

【样例3】

3

2 3 1

样例输出 Sample Output

【样例1】

a b a a b b a b

【样例2】

0

【样例3】

a c a b b d

数据范围及提示 Data Size & Hint

30%的数据满足: n<=10

50%的数据满足: n<=50

100%的数据满足: n<=1000

/*
若不能双栈排序,一定存在冲突
把冲突连边,因为只有两个栈,判断可否二分图染色即可
考虑冲突。若有i<j<k a[k]<a[i]<a[j] 则一定不能单栈排序
若i<j<k<x 有a[x]<a[i]<a[j]<a[k]则一定不能双栈排序
预处理后缀最小值,把冲突连边即可。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<queue>
#include<stack> #define N 1007
#define inf 0x3f3f3f3f
#define B 1 using namespace std;
int n,ans,cnt;
int a[N],f[N],col[N],head[N];
stack<int>s1,s2;
struct edge{
int u,v,net;
}e[N<<]; inline void add(int u,int v)
{
e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt;
} inline int read()
{
int x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} void bfs(int u)
{
queue<int>q;q.push(u);col[u]=B;
while(!q.empty())
{
int now=q.front();q.pop();
for(int i=head[now];i;i=e[i].net)
{
int v=e[i].v;
if(col[v]==-) col[v]=col[now]^,q.push(v);
else if(col[v]!=(col[now]^)){printf("0\n");exit();}
}
}
} int main()
{
memset(col,-,sizeof col);
n=read();
for(int i=;i<=n;i++) a[i]=read();
f[n+]=inf;
for(int i=n;i>=;i--) f[i]=min(f[i+],a[i]);
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(a[i]>f[j+] && a[i]<a[j]) add(i,j),add(j,i); for(int i=;i<=n;i++)
if(col[i]==-) bfs(i);
cnt=;
for(int i=;i<=n;i++)
{
if(col[i]==B) s1.push(a[i]),printf("a ");
else s2.push(a[i]),printf("c ");
while((!s1.empty() && s1.top()==cnt) || (!s2.empty() && s2.top()==cnt))
{
if(!s1.empty() && s1.top()==cnt) s1.pop(),printf("b ");
else s2.pop(),printf("d ");
++cnt;
}
}
return ;
}

双栈排序 2008年NOIP全国联赛提高组(二分图染色)的更多相关文章

  1. 1169 传纸条 2008年NOIP全国联赛提高组 个人博客:attack.cf

    1169 传纸条 2008年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond         题目描述 Description 小渊和小轩 ...

  2. Codevs 1169 传纸条 2008年NOIP全国联赛提高组

    1169 传纸条 2008年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小渊和小轩是好朋友也是同班 ...

  3. 笨小猴 2008年NOIP全国联赛提高组

    题目描述 Description 笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼.但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大! 这种方法的具体描述如下:假设m ...

  4. 火柴棒等式(2008年NOIP全国联赛提高组)

    题目描述 Description 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: ...

  5. Codevs 1218 疫情控制 2012年NOIP全国联赛提高组

    1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...

  6. Codevs 1198 国王游戏 2012年NOIP全国联赛提高组

    1198 国王游戏 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 恰逢 H 国国庆,国王邀 ...

  7. Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对

    题目:http://codevs.cn/problem/3286/ 3286 火柴排队  2013年NOIP全国联赛提高组  时间限制: 1 s   空间限制: 128000 KB   题目等级 : ...

  8. Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组

    1069 关押罪犯 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description S 城现有两座监狱,一共 ...

  9. Codevs 3289 花匠 2013年NOIP全国联赛提高组

    3289 花匠 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 花匠栋栋种了一排花,每株花都 ...

随机推荐

  1. 【KMP+最小循环节】F. Cyclic Nacklace

    https://www.bnuoj.com/v3/contest_show.php?cid=9147#problem/F [题意] 给定一个字符串,问在字符串后最少添加多少个字母,得到的新字符串能是前 ...

  2. poj1984并查集的相对偏移

    #include<stdio.h>//典型题 #include<math.h> #define N 40010 struct node { int x,y,z; }pre[N] ...

  3. java中使用Protobuf的实例(Demo)

    由于Protobuf受到推崇,故尝试采用protobuf来摒弃传统的xml进行传输数据. 首先,需要下载的关于Protobuf的文件: 1.到http://code.google.com/p/prot ...

  4. msp430入门学习10

    msp430的定时器--看门狗 msp430入门学习

  5. 从零开始写STL-内存部分-内存分配器allocator

    从零开始写STL-内存部分-内存分配器allocator 内存分配器是什么? 一般而言,c++的内存分配和释放是这样操作的 >>class Foo{ //...}; >>Foo ...

  6. CodeForces - 812C Sagheer and Nubian Market 二分

    On his trip to Luxor and Aswan, Sagheer went to a Nubian market to buy some souvenirs for his friend ...

  7. 笔记:Javac编译器

    Javac编译器是把 *.java 文件转换为 *.class 文件,是一个前端编译器:对应着有一种把字节码转变为机器码的编译器,称为JIT编译器(Just In Time Compiler),比如 ...

  8. 百度UEditor富文本上传图片

    项目中使用UEditor发现设置图片自定义保存路径会出现<请求后台配置项http错误,上传功能将不能正常使用!错误> /* 上传图片配置项 */ "imageActionName ...

  9. io计算

    http://www.cnblogs.com/yalong_xiang/archive/2011/11/15/2249530.html ぬ儱←OWEN★   windows下如何查看磁盘IO性能 复制 ...

  10. Java导出jar并运行

    1. 创建manifest.mf文件 在工程下创建manifest.mf文件.文件内容为: Manifest-version: 1.0 Main-Class: SqlCheckUtil.java 注意 ...