洛谷 P1155 【NOIP2008】双栈排序
题目链接
题解
这题有点神啊。。
我们仔细观察一下,发现两个栈内元素必须为降序
那么有结论 如果有\(i < j < k\) 且 \(a[k] < a[i] < a[j]\)则\(i\)和\(j\)不能存在于同一个栈
证明:
因为栈内元素必须降序,
那么加入\(a[j]\)时一定弹出了\(a[i]\),而又因为从小到大排序,
所以\(a[k]\)应该在\(a[i]\)前弹出,故结论正确。
证毕!
因为是两个栈
那么我们可以搞一个二分图染色
最后贪心模拟一遍
Code
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N], s1[N], s2[N], Min[N], t1, t2, ans[N<<1], len, n;
bool G[N][N], vis[N];
int z[N];
void dfs(int x, int c) {
vis[x] = 1; z[x] = c;
for (int i = 1; i <= n; i++) {
if (!G[x][i]) continue;
if (!vis[i])
dfs(i, c^1);
else if (c == z[i]) {
printf("0\n");
exit(0);
}
}
return ;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
Min[n+1] = 2147483647;
for (int i = n; i >= 1; i--)
Min[i] = min(Min[i+1], a[i]);
for (int i = 1; i < n; i++)
for (int j = i+1; j <= n; j++)
if (Min[j+1] < a[i] && a[i] < a[j])
G[i][j] = G[j][i] = 1;
for (int i = 1; i <= n; i++)
if (!vis[i])
dfs(i, 0);
int now = 1;
for (int i = 1; i <= n; i++) {
if (!z[i]) {
while (s1[t1] == now) {
now++;
t1--;
ans[++len] = 1;
}
s1[++t1] = a[i];
len++;
}
else {
while (s1[t1] == now) {
now++;
t1--;
ans[++len] = 1;
}
while (s2[t2] == now) {
now++;
t2--;
ans[++len] = 3;
}
s2[++t2] = a[i];
ans[++len] = 2;
}
}
while (now <= n) {
if (s1[t1] == now) ans[++len] = 1, t1--;
else ans[++len] = 3, t2--;
now++;
}
for (int i = 1; i <= len; i++) printf("%c ", ans[i]+'a');
return 0;
}
洛谷 P1155 【NOIP2008】双栈排序的更多相关文章
- 洛谷 1155 (NOIp2008)双栈排序——仔细分析不合法的条件
题目:https://www.luogu.org/problemnew/show/P1155 这道题教会我们要多思考. 好好分析过后发现同一个栈里不能有升序.就用它写了一个30分. #include& ...
- Luogu1155 NOIP2008 双栈排序 【二分图染色】【模拟】
Luogu1155 NOIP2008 双栈排序 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过 2个栈 S1 和 S2 ,Tom希望借助以下 44 种操作实现将输入序列升序排序. 操作 ...
- NOIP2008双栈排序[二分图染色|栈|DP]
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- noip2008 双栈排序
题目描述 Description \(Tom\)最近在研究一个有趣的排序问题.如图所示,通过\(2\)个栈\(S_1\)和\(S_2\),\(Tom\)希望借助以下\(4\)种操作实现将输入序列升序排 ...
- Noip2008双栈排序
[问题描述] 用两个栈使一个1...n的排列变得有序.一共有四个操作: A.stack1.push() 读入一个放入栈一 B.stack1.pop() 弹出栈一放入输出序列 C.stack2.push ...
- NOIP2008双栈排序(贪心)
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- [题解] [NOIP2008] 双栈排序——关系的冲突至图论解法
Problem 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操 ...
- [NOIP2008]双栈排序 【二分图 + 模拟】
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- [luogu1155 NOIP2008] 双栈排序 (二分图染色)
传送门 Description Input 第一行是一个整数 n . 第二行有 n 个用空格隔开的正整数,构成一个 1−n 的排列. Output 共一行,如果输入的排列不是"可双栈排序排列 ...
- $[NOIp2008]$双栈排序 栈/二分图/贪心
\(Sol\) 先考虑单栈排序,怎么样的序列可以单栈排序呢?设\(a_i\)表示位置\(i\)是哪个数.\(\exist i<j<k\),都没有\(a_k<a_i<a_j\), ...
随机推荐
- file_get_content() 超时
set_time_limit 只能影响php 程序的超时时间. file_get_contents 读取的是URL的超时时间. 因此 set_limit_limit 对file_get_conte ...
- iBase4j前端01_bootstrap-suggest json-server模拟后台数据、bootstrap-suggest环境搭建、开启bootstrap-suggest的post和put请求
1 准备 1.1 模拟的json数据 { "info": [ { "message": "信息", "value": [ ...
- Java-Decimal
import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; public c ...
- Hadoop完全分别式环境搭建
为学习大数据,需搭建Hadoop大数据环境,在此记录,以备以后查阅,同时分享出来,供需要者参考. 这里分几部分进行整理. 提纲: 一.说明和准备 二.设置免密登陆 分段网址:https://www.c ...
- 关于Rest Framework中View、APIView与GenericAPIView的对比分析
关于Rest Framework中View.APIView与GenericAPIView的对比分析 https://blog.csdn.net/odyssues_lee/article/detail ...
- WinAPI多线程
WIN32线程控制主要实现线程的创建.终止.挂起和恢复等操作,这些操作都依赖于WIN32提供的一组API和具体编译器的C运行时库函数.在启动一个线程之前,必须为线程编写一个全局的线程函数,一般来说,C ...
- C#序列化xml,开发常用
序列化操作对于开发人员来说最熟悉不过了. 序列化分为:序列化和反序列化. 序列化名词解释:序列化是将对象状态转换为可保持或传输的格式的过程. 与序列化相对的是反序列化,它将流转换为对象.这两个过程结合 ...
- 【Head First Java 读书笔记】(二)类与对象
前篇当中,代码都放在main()里面,那根本不是面向对象的做法. 椅子大战(对象如何改变你的一生) 程序规格: 在图形接口画出四方形,圆形和三角形,当用户点选图形时,图形需要顺时针转360度并依据形状 ...
- open与fopen的用法
1. fopen 打开普通文件 带缓冲区 缓冲文件系统是借助文件结构体指针来对文件进行管理,通过文件指针来对文件进行访问,既可以读写字符.字符串.格式化数据,也可以读写二进制数据. 函数原 ...
- githup上传文件
GitHub是基于git实现的代码托管.git是目前最好用的版本控制系统了,非常受欢迎,比之svn更好. GitHub可以免费使用,并且快速稳定.即使是付费帐户,每个月不超过10美刀的费用也非常便宜. ...