【NOIP2008】双栈排序

时间:2022-12-14 01:56:30

感觉看了题解还是挺简单的,不知道当年chty同学为什么被卡了呢么久……所以说我还是看题解了【NOIP2008】双栈排序

原题:

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

操作a
如果输入序列不为空,将第一个元素压入栈S1
操作b
如果栈S1不为空,将S1栈顶元素弹出至输出序列
操作c
如果输入序列不为空,将第一个元素压入栈S2
操作d
如果栈S2不为空,将S2栈顶元素弹出至输出序列
如果一个1~n的排列P可以通过一系列操作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”。例如(1,3,2,4)就是一个“可双栈排序序列”,而(2,3,4,1)不是。下图描述了一个将(1,3,2,4)排序的操作序列:<a,c,c,b,a,d,d,b>

【NOIP2008】双栈排序

当然,这样的操作序列有可能有几个,对于上例(1,3,2,4),<a,c,c,b,a,d,d,b>是另外一个可行的操作序列。Tom希望知道其中字典序最小的操作序列是什么。

n<=1000

非常重要的核心结论:S[i],S[j]两个元素不能进入同一个栈 <=> 存在k,满足i<j<k,使得S[k]<S[i]<S[j]

证明略(逃

(其实我连题都没研究,只是看懂这个结论,代码很容易就写出来……)

然而酱紫判断是n^3的,会T,可以用一个很简单的前缀和DP,用f[i]表示i到n的最小值,就可以用O(n^2)的时间完成判断辣

然后限制条件有了,只有两个栈,就用二分图染色

为了使字典序最小,要优先进入1栈,所以在染色的时候要使用邻接矩阵,然后按照序号递增的顺序找边染色,且第一个点要染成1栈的颜色

最后栈的分配方案给出来了,就可以用一个temp来模拟排序后的递增序列,枚举i到n,先把a[i]根据颜色进栈,然后while栈1或栈2的栈头==temp就出栈,为了使字典序最小要先出1栈

代码:

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int oo=;
/*struct ddd{int next,y;}e[2100000];int LINK[210000],ltop=0;
inline void insert(int x,int y){e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;}*/
bool e[][];//因为要按编号递增染色,所以用邻接矩阵
int n,a[];
int f[];
int color[];
int zhana[],topa=,zhanb[],topb=;
bool dfs(int x,int y){
if(color[x]!=- && color[x]==color[y]) return false;
if(color[x]==!color[y]) return true;
color[x]=!color[y];
for(int i=;i<=n;i++)if(e[x][i] && i!=y && !dfs(i,x)) return false;
return true;
}
int main(){//freopen("ddd.in","r",stdin);
memset(e,,sizeof(e));
memset(color,-,sizeof(color));
cin>>n;
for(int i=;i<=n;i++) scanf("%d",&a[i]);
f[n+]=oo;
for(int i=n;i>=;i--) f[i]=min(a[i],f[i+]);
for(int i=;i<n;i++)
for(int j=i+;j<=n;j++)if(a[i]<a[j] && f[j+]<a[i])
e[i][j]=e[j][i]=true;
for(int i=;i<=n;i++)if(color[i]==- && !dfs(i,)){ cout<<<<endl; return ;}
int temp=;//使用temp可以很方便地模拟递增序列
for(int i=;i<=n;i++){
if(!color[i]) zhana[++topa]=a[i],printf("a ");
else zhanb[++topb]=a[i],printf("c ");
while((topa && zhana[topa]==temp) || (topb && zhanb[topb]==temp)){
if(topa && zhana[topa]==temp) topa--,printf("b ");
else topb--,printf("d ");
temp++;
}
}
return ;
}

【NOIP2008】双栈排序的更多相关文章

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

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

  2. NOIP2008双栈排序&lbrack;二分图染色&vert;栈&vert;DP&rsqb;

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

  3. noip2008 双栈排序

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

  4. Noip2008双栈排序

    [问题描述] 用两个栈使一个1...n的排列变得有序.一共有四个操作: A.stack1.push() 读入一个放入栈一 B.stack1.pop() 弹出栈一放入输出序列 C.stack2.push ...

  5. NOIP2008双栈排序(贪心)

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

  6. &lbrack;题解&rsqb; &lbrack;NOIP2008&rsqb; 双栈排序——关系的冲突至图论解法

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

  7. &lbrack;NOIP2008&rsqb;双栈排序 【二分图 &plus; 模拟】

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

  8. &lbrack;luogu1155 NOIP2008&rsqb; 双栈排序 &lpar;二分图染色&rpar;

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

  9. &dollar;&lbrack;NOIp2008&rsqb;&dollar;双栈排序 栈&sol;二分图&sol;贪心

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

  10. &lbrack;NOIp2008&rsqb; 双栈排序 &lpar;二分图染色 &plus; 贪心&rpar;

    题意 给你一个长为 \(n\) 的序列 \(p\) ,问是否能够通过对于两个栈进行 push, pop(print) 操作使得最后输出序列单调递增(即为 \(1 \cdots n\) ),如果无解输出 ...

随机推荐

  1. XSS 前端防火墙 —— 整装待发

    到目前为止,我们把能用前端脚本防御 XSS 的方案都列举了一遍. 尽管看起来似乎很复杂累赘,不过那些是理论探讨而已,在实际中未必要都实现.我们的目标只是为了预警,能发现问题就行,并非要做到滴水不漏的程 ...

  2. ZooKeeper:Java客户端网络处理

    了解ZooKeeper客户端的实现,对于使用ZooKeeper的客户端非常重要. 通过对客户端源码的阅读,了解了如下信息: 创建ZooKeeper对象时,应会创建一个ClientCnxn(代表了客户端 ...

  3. mysql 基础 增删改查语句

    MySQL:众多关系型数据库中的一种仓库 --数据库箱子 --表数据库:进入mysql 命令行: mysql -uroot -p查看所有数据库: show databases;创建数据库: creat ...

  4. CapsLock与ctrl的键位修改

    windows下修改方式: linux下修改方式: 在用户目录下新建文档命名为keychange.sh 编辑以下内容: remove Lock = Caps_Lock remove Control = ...

  5. sqlalchemy ORM

    本节内容       ORM介绍     sqlalchemy安装     sqlalchemy基本使用     多外键关联     多对多关系   1. ORM介绍   orm英文全称object ...

  6. Leetcode 210 Course Schedule II

    here are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prere ...

  7. C&num;中的二进制序列化和Json序列化

    序列化就是把一个对象变成流的形式,方便传输和还原.小弟不才,总结下对二进制序列化和Json序列化的使用: 1.首先,二进制序列化(BinaryFormatter)要求要序列化的类必须是可序列化的(即在 ...

  8. 连接池dbcp pool

    -package cn.gdpe.pool; import java.io.InputStream;import java.sql.Connection;import java.sql.Prepare ...

  9. Centos6&period;5源码编译安装nginx

    1.安装pcre下载地址:http://jaist.dl.sourceforge.net/project/pcre/pcre/8.38/pcre-8.38.tar.gz #tar -axvf pcre ...

  10. 如何成为CSDN博客专家

    先看一下官方给出的要求: 申请CSDN博客专家应具备的条件: 1.原创IT类文章总数超过20篇,并且最近一个月内发布了新的原创IT类文章. 2.博客文章总的浏览量超过5万次以上. 3.文章内容的质量很 ...