1170 雙棧排序

2022-05-03 10:54:26 字數 1809 閱讀 1451

2023年noip全國聯賽提高組

description

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)排序的操作序列:

當然,這樣的操作序列有可能有幾個,對於上例(1,3,2,4),是另外乙個可行的操作序列。tom希望知道其中字典序最小的操作序列是什麼。

input description

輸入的第一行是乙個整數n。

第二行有n個用空格隔開的正整數,構成乙個1~n的排列。

output description

輸出共一行,如果輸入的排列不是「可雙棧排序排列」,輸出數字0;否則輸出字典序最小的操作序列,每兩個操作之間用空格隔開,行尾沒有空格。

sample input

【樣例1】

41 3 2 4

【樣例2】

42 3 4 1

【樣例3】

32 3 1

sample output

【樣例1】

a b a a b b a b

【樣例2】

0【樣例3】

a c a b b d

data size & hint

30%的資料滿足: n<=10

50%的資料滿足: n<=50

100%的資料滿足: n<=1000

大陸地區

noip全國聯賽提高組

2023年

題解:如果存在(i

預處理i ,j (i

做一遍染色即可,出現非法情況(同一點染上不同顏色)就無解。

讓完後做乙個簡單的字典序最小進棧出棧操作,記下當前要出棧的數,然後依題意搞之即可

ac**:

#include#include

#include

using

namespace

std;

const

int n=1e4+10

;struct

nodee[n

<<6

];int

n,tot,head[n];

int a[n],color[n],f[n][21

];int

top1,top2,s1[n],s2[n];

bool

flag;

void add(int x,int

y)void

rmq()

}}int query(int i,int

j)void paint(int

x)

else

if(color[e[i].v]==color[x])

}}int

main()

}for(int i=1;i<=n;i++) if(!color[i])

}int now=1

;

for(int i=1;i<=n;i++)

else

}else

else}}

for(int i=now;i<=n;i++)

return0;

}

codevs 1170 雙棧排序

好題啊 好題啊 而然還是看了一眼題解啊 有那麼一點思路 但是離寫出 還很遠 考慮必須分開放倒兩個棧裡的情況 即存在i include include include define maxn 1010 using namespace std int n,m,a maxn num,head maxn c...

雙棧排序(codevs 1170)題解

tom最近在研究乙個有趣的排序問題。如圖所示,通過2個棧s1和s2,tom希望借助以下4種操作實現將輸入序列公升序排序。操作a如果輸入序列不為空,將第乙個元素壓入棧s1 操作b如果棧s1不為空,將s1棧頂元素彈出至輸出序列 操作c如果輸入序列不為空,將第乙個元素壓入棧s2 操作d如果棧s2不為空,將...

1002 雙棧排序

description tom最近在研究乙個有趣的排序問題。如圖所示,通過2個棧s1和s2,tom希望借助以下4種操作實現將輸入序列公升序排序。操作a 如果輸入序列不為空,將第乙個元素壓入棧s1 操作b 如果棧s1不為空,將s1棧頂元素彈出至輸出序列 操作c 如果輸入序列不為空,將第乙個元素壓入棧s...