P1155 [NOIP 2008 提高组] 双栈排序
将一组数据分成两组,且组内不能冲突。考虑使用二分图。
我们来思考什么样的两个数不能存在于一个栈中。因为最后要求我们升序排序输出,所以在一个栈中的数字必定是降序。
那么当 \(i<j\) 时并且 \(p_i<p_j\)。\(i,j\) 便不能存在于同一个栈中吗?
显然不是,我们来看 \(P=\left [1,3,2,4\right ]\)。前两个数 \(1,3\) 是可以满足上文的情况的,但是他们可以存在在一个栈里面。为什么会造成这种情况呢?我们发现数字 \(1\) 入栈后就可以直接弹,因为它后面没有比它小的数字了。
所以我们还要加一个附加条件。即当 \(i<j<k\) 且 \(p_k<p_i<p_j\) 满足时,\(i,j\) 不能共存于一个栈中。之后我们便在 \(i,j\) 之间建边,去做二分图即可。
之后我们考虑如何让字典序最小,观察到两个栈的操作是独立的,那么如果相邻的两个操作是一个栈插入,另一个栈弹出,那么可以交换位置,以此让字典序达到最小。
讲的很详细了,代码就不放注释了。
#include<bits/stdc++.h>
using namespace std;
const int N=1007;
int n,a[N],cnt=1,tot;
stack<int> s1,s2;
vector<int> G[N];
char ans[N*3];
bool vis[N],col[N];
void dfs(int u,int co){
// cout<<u<<' '<<co<<'\n';
vis[u]=1,col[u]=co;
for(auto v:G[u]){
if(vis[v]) {
if(col[v]==col[u]) {
cout<<0;
exit(0);
}
continue;
}
dfs(v,co^1);
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=n-1,x=a[n];i>1;i--){
for(int j=i-1;j>=1;j--){
if(a[j]<a[i]&&x<a[j]) G[a[j]].push_back(a[i]),G[a[i]].push_back(a[j]);
}
x=min(x,a[i]);
}
for(int i=1;i<=n;i++){
if(!vis[a[i]]) dfs(a[i],0);
}
// for(int i=1;i<=n;i++) cout<<col[i]<<' ';
// cout<<'\n';
for(int i=1;i<=n;i++){
if(col[a[i]]==0) ans[++tot]+='a',s1.push(a[i]);
else ans[++tot]+='c',s2.push(a[i]);
while((!s1.empty()&&s1.top()==cnt)||(!s2.empty()&&s2.top()==cnt)){
if(!s1.empty()&&s1.top()==cnt) ans[++tot]='b',s1.pop(),cnt++;
else ans[++tot]='d',s2.pop(),cnt++;
}
}
for(int i=tot-1;i>=1;i--){
for(int j=i;j<tot;j++){
if((ans[j]=='c'&&ans[j+1]=='b')||(ans[j]=='d'&&ans[j+1]=='a')) swap(ans[j],ans[j+1]);
else break;
}
}
for(int i=1;i<=tot;i++) cout<<ans[i]<<' ';
return 0;
}
P1155 [NOIP 2008 提高组] 双栈排序的更多相关文章
- NOIp2018提高组 双栈排序
这真是道神奇的题目: 原题链接 首先我们要证明以下的性质: 若原序列为\(\{a_n\}\),\(a_i\)和\(a_j\)不能同时放入一个栈中,当且仅当\(i<j,a_i<a_j\),且 ...
- NOIP 2008提高组第三题题解by rLq
啊啊啊啊啊啊今天已经星期三了吗 那么,来一波题解吧 本题地址http://www.luogu.org/problem/show?pid=1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们 ...
- BZOJ 2080: [Poi2010]Railway 双栈排序
2080: [Poi2010]Railway Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 140 Solved: 35[Submit][Statu ...
- 双栈排序 2008年NOIP全国联赛提高组(二分图染色)
双栈排序 2008年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description Tom最近在研究一个有 ...
- [NOIP2008] 提高组 洛谷P1155 双栈排序
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- NOIP 2008 双栈排序
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- 【提高组NOIP2008】双栈排序 (twostack.pas/c/cpp)
[题目描述] Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈 ...
- P1155 双栈排序(二分图染色)
P1155 双栈排序(二分图染色) 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一 ...
- 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)
洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...
- P1155 双栈排序
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作aaa 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果 ...
随机推荐
- glib-2.60在win64,msys2下编译
前阵子,工作原因,需要在win7 64下的msys2来编译glib,下面是一些踩过的坑: 事先声明一下,这些个解决方式及纯粹是为了编译通过,可能有些做法不太适合一些需要正常使用的场合,烦请各位注意下. ...
- mysql 表的创建,修改,删除
查看数据库所有表 show tables 创建 create table 表名 ( 列名 类型 约束条件 ... ) 类型有整形: tinyint(1B) ,smallint(2B),mediumin ...
- 解决PyCharm提示Error: Please select a valid Python interpreter
前言 Pycharm运行Python3.7.8的程序时发现源程序运行报错(非语法错误) Error:please select a valid Python interpreter 解决 第一步:打开 ...
- go string转int strconv包
前言 strconv 主要用于字符串和基本类型的数据类型的转换 s := "aa"+100 //字符串和整形数据不能放在一起 所以需要将 100 整形转为字符串类型 //+号在字符 ...
- Camel多智能体框架初探
Camel介绍 CAMEL 是一个开源社区,致力于探索代理的扩展规律.我们相信,在大规模研究这些代理可以提供对其行为.能力和潜在风险的宝贵见解.为了促进该领域的研究,我们实现了并支持各种类型的代理.任 ...
- 动态规划--最长公共子序列( LCS 问题)
博客地址:https://www.cnblogs.com/zylyehuo/ # -*- coding: utf-8 -*- # 最长公共子序列的长度 def lcs_length(x, y): m ...
- Delphi 禁止重复运行程序的方法
第一种方法,使用"过程调用" procedure Del; // 自定义过程 var Mutex: THandle; begin Mutex := CreateMutex(nil, ...
- g2o优化库实现曲线拟合
g2o优化库实现曲线拟合 最近学习了一下g2o优化库的基本使用,尝试着自己写了一个曲线拟合的函数,也就是下面这个多项式函数: \[y = ax^3 + bx^2 + cx + d \] 我们以 \(a ...
- C# Socket的使用方法 及 简单实例
核心: 在服务器端和客户端的两个Socket实例,共同维持一个连接,而我们还需要一个服务端绑定了特定端口号的固定的serverSocket,用来监听远方clientSocket的申请,并为这个申请建立 ...
- Java并发编程实战-多线程任务执行
Executor框架与线程池(ThreadPoolExecutor) Executor框架的组成 组件 作用 Executor 基础接口,仅定义execute(Runnable)方法,用于执行任务. ...