题目传送门

  传送门I

  传送门II

题目大意

  双栈排序,问最小字典序操作序列。

  不能发现两个数$a_{j}, a_{k}\ \ (j < k)$不能放在同一个栈的充分必要条件时存在一个$i$使得$j < k < i$且$a_{i} < a_{j} < a_{k}$。

  证明?写个dfs就证完了(就是考虑任意一个三元组)。

  然后可建图,对于满足上面条件的$(j, k)$,$j$和$k$连一条无向边。

  显然必要条件时图不存在奇环,即能够二分染色。

  再证明一下这是必要条件。

  我们先构造一个做法:硬点二分染色完白点扔第一个栈里,黑点扔第二个栈里,当当前需要输出的数能够输出的时候就输出,否则继续加数。

  我们只需要证明每个数都能被正确的输出就行了。

  显然第1个数一定能被正确地输出。

  假设前$k - 1\ \ \ (k > 1)$个数已经被正确地输出了,考虑第$k$个数。

  • 第$k$个数不在栈中,那么还剩在序列中,我们把之间的数加入栈中,再把它加入弹出,它就正确地输出了。
  • 第$k$个数在栈中
    • 某个栈的栈顶,直接弹出,正确地输出了。
    • 否则它上面一定存在一个数$x > k$使得它无法弹出。
      • 如果$1, 2, \dots, k - 1$中都在$k$之前,那么输出完前$k - 1$个数后,$k$入栈后就可以弹出并输出了,与做法矛盾。
      • 否则存在一个$y < x$在$k$之后,由建图方法和染色可知$k, x$不能在同一个栈中,矛盾。

  因此图能够二分染色是存在解的充分必要条件。

  然后拿个栈直接贪心就好了。每次选择能够进行的字典序最小的操作。

Code

 /**
* Vijos
* Problem#1605
* Accepted
* Time: 42ms
* Memory: 1.363m
*/
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
typedef bool boolean; const int N = 1e3 + ; int n;
int ar[N];
int mns[N];
boolean g[N][N]; inline void init() {
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%d", ar + i);
} int col[N];
boolean color(int p, int col) {
if (::col[p] != -)
return ::col[p] == col;
::col[p] = col;
for (int i = ; i <= n; i++)
if (g[p][i] && !color(i, col ^ ))
return false;
return true;
} int s1[N], s2[N];
int tp1, tp2; inline void solve() {
mns[n] = ar[n];
for (int i = n - ; i; i--)
mns[i] = min(mns[i + ], ar[i]);
for (int i = ; i < n; i++)
for (int j = i + ; j < n; j++)
if (ar[i] < ar[j] && mns[j] < ar[i])
g[i][j] = g[j][i] = true;
memset(col, -, sizeof(col));
for (int i = ; i <= n; i++)
if (col[i] == - && !color(i, )) {
puts("");
return;
} int cur = , p = ;
while (cur <= n) {
if (p <= n && !col[p] && s1[tp1] != cur)
putchar('a'), s1[++tp1] = ar[p++];
else if (s1[tp1] == cur)
putchar('b'), tp1--, cur++;
else if (p <= n && col[p] && s2[tp2] != cur)
putchar('c'), s2[++tp2] = ar[p++];
else
putchar('d'), tp2--, cur++;
putchar(' ');
}
} int main() {
init();
solve();
return ;
}

vijos 1605 双栈排序 - 贪心 - 二分图的更多相关文章

  1. 洛谷$P1155$ 双栈排序 贪心+二分图匹配

    正解:贪心+二分图匹配 解题报告: 传送门$QwQ$ 跪了,,,我本来以为我$NOIp$做得差不多了,,,然后康了一眼发现没做多少啊其实$QAQ$ 然后来康题趴$QwQ$ 首先考虑如果只有一个栈的情况 ...

  2. P1155 双栈排序(二分图染色)

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

  3. [NOIP2008]双栈排序 【二分图 + 模拟】

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

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

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

  5. [LuoguP1155]双栈排序_二分图_bfs

    双栈排序 题目链接:https://www.luogu.org/problem/P1155 数据范围:略. 题解: 神仙题. 就第一步就够劝退了. 这个二分图非常不容易,首先只有两个栈,不是属于一个就 ...

  6. 洛谷P1155 双栈排序(贪心)

    题意 题目链接 Sol 首先不难想到一种贪心策略:能弹则弹,优先放A 然后xjb写了写发现只有\(40\),原因是存在需要决策的情况 比如 \(A = {10}\) \(B = {8}\) 现在进来一 ...

  7. 【Luogu】P1155双栈排序(二分图)

    题目链接在此 此题一开始写了个深搜,过了30%的数据,也就是n<=10的那一段.... 然后看了题解发现这是个二分图的判断. 我们先举例子找到不能放进一个栈里的规律.设有数列[2,3,1,4] ...

  8. $[NOIp2008]$双栈排序 栈/二分图/贪心

    \(Sol\) 先考虑单栈排序,怎么样的序列可以单栈排序呢?设\(a_i\)表示位置\(i\)是哪个数.\(\exist i<j<k\),都没有\(a_k<a_i<a_j\), ...

  9. 双栈排序(洛谷P1155)二分图的判定+思维贪心

    题目:戳这里 题目大意: 给你一个数列,问能否通过两个栈的push与pop把它输出成一个升序序列(每个数只能入队并出队一次) 不能的话输出0,能的话输出操作方法 主要思路: 1.判断是否可以成功输出升 ...

随机推荐

  1. python pytest测试框架介绍五---日志实时输出

    同样的,在使用pytest进行自动化测试时,需要将实时日志打印出来,而不是跑完后才在报告中出结果. 不过,好在pytest在3.3版本开始,就支持这一功能了,而不用再像nose一样,再去装第三方插件. ...

  2. Go语言基础之数据类型

    Go语言基础之数据类型 Go语言中有丰富的数据类型,除了基本的整型.浮点型.布尔型.字符串外,还有数组.切片.结构体.函数.map.通道(channel)等.Go 语言的基本类型和其他语言大同小异. ...

  3. N - Asteroids

    Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N g ...

  4. JS创建对象的几种方式整理

    javascript是一种“基于prototype的面向对象语言“,与java有非常大的区别,无法通过类来创建对象.那么,既然是面象对象的,如何来创建对象呢? 一:通过“字面量”方式创建对象 方法:将 ...

  5. 一次CTF后对二维码的认识

    前一段时间参加一个CTF比赛的时候其中有一个题目就是一张二维码图片,然后获取其中的信息来解题,那个二维码的特别之处在于,它把3个位置探测区域用几张美女图片代替了,然后在做题的时候顺便简单的了解了一下二 ...

  6. css 获取从第n个开始,之后的所有元素

    <div id="box"> <div></div> <div>等待获取</div> <div>等待获取&l ...

  7. mybatis05--多条件的查询

    public interface StudentDao { /** * 前台的表单给出的查询条件不能封装成一个对象的时候 * 查询只能是多个参数了! 也就是参数不全是Student中的属性! * 这时 ...

  8. django form 组件插件

    创建类: class RegForms(forms.Form): account = fields.CharField( required = True, #必填字段 max_length=12, m ...

  9. NodePort 只能在node节点上访问,外部无法访问

    创建了一个NodePort类型的jenkins service,node port 30000,node节点ip为192.168.56.101, 在node节点上通过浏览器能正常访问http://19 ...

  10. 有多个正整数存放在数组中,编写一个函数要求偶数在左边由小到大顺序放置,奇数在右边,也是由小到大顺序放置,Java实现

    思路: * 1.首先分左右 * 2.分好再排序(左边和右边都单独排序) 第一步:分左右 可得注意了: 大体思路最先是从两头出发分成4种情况讨论(左or右,奇数or偶数)循环处理,出口是双层的嵌套循环( ...