这真是道神奇的题目:

原题链接

首先我们要证明以下的性质:

若原序列为\(\{a_n\}\),\(a_i\)和\(a_j\)不能同时放入一个栈中,当且仅当\(i<j,a_i<a_j\),且存在\(k\),\(s.t. \ k>j\)的同时有\(a_k<a_i\)。

原因很显然,因为有比\(a_i\)还小的元素在后面,若放入同一个栈中,必须先压栈压到\(a_k\),再弹出,但又因为会先弹出\(a_j\),序列的单调性就被破坏了。

所以对于每一对\(a_i\)和\(a_j\),我们都可以用上述性质来判断它们是否能在同一个栈中,再用后缀最大值优化一下,复杂度\(O(n^2)\)。

然后我们就有了这样的一些关系,我们该如何利用这些关系来判断序列是否合法呢?

二分图染色,对于不能在同一个栈中的两个位置,我们连一条无向边,然后dfs判断所有点能否二染色。如果能,序列就是合法的,否则不合法。

对于染色后的图,其实我们已经知道操作顺序了,又因为题目要求字典序最小,所以我们只用模拟一下,优先在栈\(S1\)上操作就行了。

上代码:

#include <bits/stdc++.h>

using namespace std;

#define wrap cout << endl

const int N = 1000;

int n, a[N+5], color[N+5], f[N+5], flag;
vector<int> G[N+5]; void addEdge(int u, int v) {
G[u].push_back(v);
G[v].push_back(u);
} void dfs(int u) {
for(int i = 0; i < G[u].size(); ++i) {
int v = G[u][i];
if(color[v]) {
if(color[v] == color[u])
flag = 1;
}
else {
color[v] = 3-color[u];
dfs(v);
}
}
} void solve() {
int cur = 1;
stack<int> s1, s2;
for(int i = 1; i <= n; ++i) { //模拟
if(color[i] == 1) s1.push(a[i]), cout << 'a' << " ";
if(color[i] == 2) s2.push(a[i]), cout << 'c' << " ";
while((!s1.empty() && s1.top() == cur) || (!s2.empty() && s2.top() == cur)) {
if(!s1.empty() && s1.top() == cur) s1.pop(), cout << 'b' << " ";
if(!s2.empty() && s2.top() == cur) s2.pop(), cout << 'd' << " ";
++cur;
}
}
} int main() {
cin >> n;
for(int i = 1; i <= n; ++i) cin >> a[i];
f[n+1] = 0x3f3f3f3f;
for(int i = n; i >= 1; --i) f[i] = min(f[i+1], a[i]);
for(int i = 1; i <= n; ++i)
for(int j = i+1; j <= n; ++j)
if(a[i] < a[j] && f[j+1] < a[i]) addEdge(i, j); //判断是否加边
for(int i = 1; i <= n; ++i)
if(!color[i])
color[i] = 1, dfs(i);
if(flag) {
cout << "0" << endl;
return 0;
}
solve();
return 0;
}

NOIp2018提高组 双栈排序的更多相关文章

  1. 双栈排序 2008年NOIP全国联赛提高组(二分图染色)

    双栈排序 2008年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master     题目描述 Description Tom最近在研究一个有 ...

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

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

  3. 【提高组NOIP2008】双栈排序 (twostack.pas/c/cpp)

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

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

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

  5. 双栈排序(codevs 1170)题解

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

  6. [NOIp2018提高组]赛道修建

    [NOIp2018提高组]赛道修建 题目大意: 给你一棵\(n(n\le5\times10^4)\)个结点的树,从中找出\(m\)个没有公共边的路径,使得第\(m\)长的路径最长.问第\(m\)长的路 ...

  7. [NOIp2018提高组]货币系统

    [NOIp2018提高组]货币系统 题目大意: 有\(n(n\le100)\)种不同的货币,每种货币的面额为\([1,25000]\)之间的一个整数.若两种货币系统能够组合出来的数是相同的的,那我们就 ...

  8. NOIP2018提高组省一冲奖班模测训练(四)

    NOIP2018提高组省一冲奖班模测训练(四) 这次比赛只AC了第一题,而且花了40多分钟,貌似是A掉第一题里面最晚的 而且还有一个半小时我就放弃了…… 下次即使想不出也要坚持到最后 第二题没思路 第 ...

  9. NOIP2018提高组省一冲奖班模测训练(三)

    NOIP2018提高组省一冲奖班模测训练(三) 自己按照noip的方式考,只在最后一两分钟交了一次 第一题过了,对拍拍到尾. 第二题不会.考试时往组合计数的方向想,推公式,推了一个多小时,大脑爆炸,还 ...

随机推荐

  1. TCP/IP、UDP、HTTP、SOCKET详解

    文章大纲 网络OSI七层及各层作用 TCP与UDP基本介绍 TCP连接过程详解 SOCKET原理与连接详解     一.网络OSI七层及各层作用   应用层:文件传输,电子邮件,文件服务,虚拟终端 T ...

  2. SC命令

    描述:         SC 是用来与服务控制管理器和服务进行通信         的命令行程序. 用法:         sc <server> [command] [service n ...

  3. MongoDB 中的【加减乘除】运算

    很多同学因为对MongoDB不熟悉,加之应用的不是很多,有时候会认为MongoDB数据库对一些功能不支持,或者认为支持不好.今天我们 演示一下 MongoDB对“加减乘除”的使用. 在MongoDB数 ...

  4. win10安装JDK详细教程

    电脑进行了重装机器.需要重新安装,在此记录一下. 点击下一步.选择安装路径 . 等待后,选择安装位置. 点击下一步,继续等待. 安装完成. 设置环境变量 在桌面右键单击 我的电脑→属性→高级系统设置→ ...

  5. c/c++ 多线程 thread_local 类型

    多线程 thread_local 类型 thread_local变量是C++ 11新引入的一种存储类型. thread_local关键字修饰的变量具有线程周期(thread duration), 这些 ...

  6. 歌曲的BPM (Beat Per Minute)--每分钟节拍数

    因为老爸喜欢跳舞,总让我帮他整理舞曲,一会儿要慢三,一会儿要慢四,一会儿又要快四....我真的分不清啊 我想啊,慢三,慢四这些应该是歌曲的节拍吧(后来得知专业术语叫BPM),于是就在网上搜看看能不能通 ...

  7. 让 Windows7 - 64bit 支持 VC++ 6.0 的解决方法(无法启动此程序,因为计算机中丢失 MSVCRTD.dll。尝试重新安装该程序以解决此问题)

    源地址:https://www.cnblogs.com/poissonnotes/p/4372136.html 无法启动此程序,因为计算机中丢失 MSVCRTD.dll.尝试重新安装该程序以解决此问题 ...

  8. zabbix3.4监控Linux客户端

    环境准备 zabbix-server IP:192.168.1.242 nds-server  IP:192.168.1.202 web-server IP:192.168.1.203 客户端部署 关 ...

  9. Windows使用MongoDB,以及索引创建

    安装MongoDB https://www.mongodb.com/download-center#community 点击msi安装程序进行安装,可以进行自定义安装,选择安装位置,我选择的是D盘 在 ...

  10. linux ssh免密登陆远程服务器

    10.170.1.18服务器免密登录到10.170.1.16服务器 首先登入一台linux服务器(10.170.1.18),此台做为母机(即登入其他linux系统用这台做为入口):执行一行命令生成ke ...