雙棧排序(codevs 1170)題解

2022-08-30 12:15:09 字數 2777 閱讀 5635

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希望知道其中字典序最小的操作序列是什麼。

41 3 2 4

a b a a b b a b

42 3 4 103

2 3 1

a c a b b d

本題為noip2008提高組第四題,初看覺得這應該是有史以來最水的提高組最後一題了,這不是模擬嗎?只不過模擬的東西多了一點而已,然而,當我寫著寫著,就發現模擬的有點不對勁了……

好吧,這道題的正解應該是圖的染色+模擬……

是的,沒錯,你沒有看錯,第四題居然要模擬!!!

那麼問題來了……挖掘機哪家……不對……怎麼區分始終不能放在乙個棧中的數呢?

如果存在k使得i

我們可以手推一下,如果k>j>i說明,j在i的後面進棧,k在j的後面進棧,而此時ai

染完色後就好辦了,直接模擬進棧出棧的過程……如果是最小值,就出,否則就進,然後因為已經染了色了,根據染的色判斷它是進(出)棧1還是棧2,然後輸出相應的字元即可。

現在還有乙個最最擔心的問題,怎麼確定這個數是不是當前需要出棧的數(即最小值)?好吧……其實是我眼睛瞎了,是的,我為此糾結了半天,然後看題目……乙個1~n的排列p……直接最小值賦值為1,然後出棧了就inc……

1

uses math;

2var flag:array[1..1000,1..1000] of

boolean;

3 q1,q2,color,a,f:array[1..1001] of

longint;

4n,i,j,sum,t1,t2:longint;

5procedure

dfs(x,c:longint);

6var

i:longint;

7begin

8 color[x]:=c;

9for i:=1

to n do

10if flag[x,i] then

11begin

12if color[i]=c then

13begin

14 writeln(0

);15

halt;

16end;17

if color[i]=0

then

18 dfs(i,3-c);

19end;20

end;

21begin

22readln(n);

23for i:=1

to n do

24read(a[i]);

25 f[n+1]:=maxlongint;

26for i:=n downto1do

27 f[i]:=min(a[i],f[i+1

]);28

for i:=1

to n-1

do29

for j:=i+1

to n do

30if (a[i]and(f[j+1]then

31begin

32 flag[i,j]:=true;

33 flag[j,i]:=true;

34end;//初始化,哪些是始終無法進同乙個棧的

35for i:=1

to n do

36if color[i]=0

then

37 dfs(i,1);//給每乙個數染色

38 sum:=1;39

for i:=1

to n do

40begin

41if color[i]=1

then

42begin

43inc(t1);

44 q1[t1]:=a[i];

45 write('a '

);46

end47

else

48begin

49inc(t2);

50 q2[t2]:=a[i];

51 write('c '

);52

end;

53while ((t1<>0)and(q1[t1]=sum))or((t2<>0)and(q2[t2]=sum)) do

54begin

55if (0

<>t1)and(q1[t1]=sum) then

56begin

57dec(t1);

58 write('b '

);59

end60

else

61begin

62dec(t2);

63 write('d '

);64

end;

65inc(sum);//最小值

66end;67

end;//最噁心的模擬……

68end.

codevs 1170 雙棧排序

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

1170 雙棧排序

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

1002 雙棧排序

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