题目大意

  运用两个栈的push和pop操作使得一个序列单调递增且操作字典序最小。$n\leq 1000$。

题解

  本题我们要尝试运用“瞪眼法”,也就是推样例。我们显然要数字尽可能地推入第一个栈。那么问题就是:怎样的两个数字不可以在同一个栈中呢?这样的效果是:当一个数字a想要出栈时,其上端有个被他大的数字b挡着,且是不得不挡着。怎么会“不得不”呢?那是因为有一个数字c<a在b的上面(原序列中,c在b的右面),因为要想使输出序列递增,必须把b入了栈以后才能出栈。所以,a和c不能共存。将所有满足a、c这样的条件的点连边,进行二分图染色(进入栈的编号)(染不了色输出-1),然后模拟即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std; const int MAX_NODE = 1010, MAX_EDGE = MAX_NODE * MAX_NODE;
vector<char> Ops; struct Node;
struct Edge; struct Node
{
Edge *Head;
int Color;
}_nodes[MAX_NODE];
int TotNode;
Node *A[MAX_NODE];
stack<Node*> St[3]; struct Edge
{
Node *To;
Edge *Next;
}_edges[MAX_EDGE];
int _eCount; void Dfs(Node *cur, int color)
{
if (cur->Color && cur->Color != color)
{
printf("0\n");
exit(0);
}
if (cur->Color)
return;
cur->Color = color;
for (Edge *e = cur->Head; e; e = e->Next)
Dfs(e->To, color == 1 ? 2 : 1);
} void AddEdge(Node *from, Node *to)
{
Edge *e = _edges + ++_eCount;
e->To = to;
e->Next = from->Head;
from->Head = e;
} void Build(Node *u, Node *v)
{
AddEdge(u, v);
AddEdge(v, u);
} void BuildGraph()
{
static Node *AftMinV[MAX_NODE];
AftMinV[TotNode] = A[TotNode];
for (int i = TotNode - 1; i >= 1; i--)
AftMinV[i] = min(A[i], AftMinV[i + 1]);
for (int i = 1; i <= TotNode; i++)
for (int j = i + 1; j <= TotNode; j++)
if (A[i] < A[j] && AftMinV[j] < A[i])
Build(A[i], A[j]);
} int main()
{
scanf("%d", &TotNode);
for (int i = 1; i <= TotNode; i++)
{
int vId;
scanf("%d", &vId);
A[i] = _nodes + vId;
}
BuildGraph();
for (int i = 1; i <= TotNode; i++)
if (!A[i]->Color)
Dfs(A[i], 1);
Node *cur = _nodes + 1;
for (int i = 1; i <= TotNode; i++)
{
Ops.push_back(A[i]->Color == 1 ? 'a' : 'c');
St[A[i]->Color].push(A[i]);
while (!St[cur->Color].empty() && St[cur->Color].top() == cur)
{
St[cur->Color].pop();
Ops.push_back(cur->Color == 1 ? 'b' : 'd');
cur++;
}
}
for (unsigned int i = 0; i < Ops.size(); i++)
printf("%c ", Ops[i]);
printf("\n");
return 0;
}

  

luogu1155 双栈排序的更多相关文章

  1. Luogu1155 NOIP2008 双栈排序 【二分图染色】【模拟】

    Luogu1155 NOIP2008 双栈排序 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过 2个栈 S1 和 S2 ,Tom希望借助以下 44 种操作实现将输入序列升序排序. 操作 ...

  2. [luogu1155 NOIP2008] 双栈排序 (二分图染色)

    传送门 Description Input 第一行是一个整数 n . 第二行有 n 个用空格隔开的正整数,构成一个 1−n 的排列. Output 共一行,如果输入的排列不是"可双栈排序排列 ...

  3. NOIP2008双栈排序[二分图染色|栈|DP]

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

  4. noip2008 双栈排序

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

  5. BZOJ 2080: [Poi2010]Railway 双栈排序

    2080: [Poi2010]Railway Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 140  Solved: 35[Submit][Statu ...

  6. 双栈排序(codevs 1170)

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

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

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

  8. [NOIP2008] 提高组 洛谷P1155 双栈排序

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

  9. 【NOIP2008】双栈排序

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

随机推荐

  1. python清除字符串中无用字符

    将列表val_list中包含的非法字符去掉,illegal_char是非法字符列表 def clear(): illegal_char = [' ','#','%','_','@'] tmp_list ...

  2. 「 Luogu P2196 」 挖地雷

    # 解题思路 跑 $\text{n}$ 遍 $\text{spfa}$ 并记录路径,找到比当前最长路长的就更新答案,并且将路径也更新,注意起点的处理. # 附上代码 #include <iost ...

  3. 大项目之网上书城(八)——数据库大改&添加图书

    目录 大项目之网上书城(八)--数据库大改&添加图书 主要改动 1.数据库新增表 代码 2.数据库新增触发器 3.其他对BookService和BookDao的修改 代码 4.addBook. ...

  4. Linux一键安装web环境全攻略phpstudy版

    此教程主要是应对阿里云Linux云服务器ecs的web环境安装,理论上不限于阿里云服务器,此教程对所有Linux云服务器都具有参考价值. 写这篇文章的目的:网上有很多关于Linux一键安装web环境全 ...

  5. c++基础_矩阵乘法

    #include <iostream> using namespace std; int main(){ int a,b; cin>>a>>b; long c[a] ...

  6. 后端传前端数据乱码(返回json字符串到前端)

    中文乱码的问题,在开发过程中难免会遇到,而在配置好编码之后,不管是数据库,还是其他地方都配置好统一UTF-8编码之后,后端从数据库取出数据传回前端,还会乱码,这里以ssm框架为例,因为是我自己遇到的, ...

  7. IP_MULTICAST_LOOP

    WINDOWS 中 该选项仅控制接收部分.即设置为0 则控制套接字无法接收自身消息.设置为1 则控制套接字使能接收自身消息. LINUX         中 该先项仅控制发送部分.即设置为0 则控制套 ...

  8. C语言的移位操作符及位运算

    C语言的移位操作符 位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算.位移位运算符分为左移和右移两种,均为双目运算符.第一运算对象是移位对象,第二个运算对象是所移的二进制位数. 位 ...

  9. 洛谷 4932 洛谷10月月赛II T1 浏览器

    [题解] x xor y的结果在二进制下有奇数个1,等价于x与y在二进制下的1的个数之和为奇数,因为x xor y减少的1的个数一定是偶数(两个数这一位都为1,xor的结果为0,减少了2个1) 那么答 ...

  10. 集训第四周(高效算法设计)M题 (扫描法)

    原题:UVA11078 题意:给你一个数组,设a[],求一个m=a[i]-a[j],m越大越好,而且i必须小于j 怎么求?排序?要求i小于j呢.枚举?只能说超时无上限.所以遍历一遍数组,设第一个被减数 ...