UOJ 152 漢諾塔 題解

2021-08-01 14:52:27 字數 1665 閱讀 3117

三根柱子,n

nn 個盤子,編號 1

11~n

nn,開始時盤子亂序套在一根柱子上。

構造一種方案,用 106

10^6

106 以內步數使所有盤子以遞增序套在一根柱子上。

n ≤1

04

n \leq 10^4

n≤10

4這個題的目的是要把盤子排序。

1 04

10^4

104 和 106

10^6

106 是什麼關係呢?——n

log⁡

nn \log n

nlogn?

n

log⁡

nn \log n

nlog

n 有什麼排序演算法呢?——快排?歸併?

要用乙個不太依賴比較的排序,於是選擇歸併。

設當前柱子我們對 [l,

r]

[l,r]

[l,r

] 進行排序,那麼可以把盤子平均分到另兩根柱子上,把他們分別排好序,再線性合併。

這樣就是 o(n

log⁡n)

o(n \log n)

o(nlogn)

的了。

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

const

int maxn=

1e4+

5, maxk=

1e6+5;

struct op

;int n,ans0;

vector<

int> a;

op ans[maxk]

;int d0,d[maxn]

;voiddq(

int a,

int b,

int c,vector<

int>

&v);

v1.push_back

(-v[i-1]

);}fd

(i,sz,mid+1)

; v2.

push_back

(-v[i-1]

);}dq

(b,a,c,v1);dq

(c,a,b,v2);

d0=0;

for(

int i=

0, j=

0; i(i(j>=sz2 ||

-v1[i]

>

-v2[j]))

;}else;}

v.clear()

;fd(i,d0,

1) v.

push_back

(d[i]);

}int

main()

dq(1,

2,3,a)

;printf

("%d\n"

,ans0);fo

(i,1

,ans0)

printf

("%d %d\n"

,ans[i]

.a,ans[i]

.b);

}

UOJ 152 漢諾塔 分治

題目鏈結 題意 有三根編號為 1,2,3 的柱子,然後第一根柱子上有編號為 1 sim n n leq 10000 的盤子,從上到下第 i 個盤子的編號是 a i 其他兩根柱子是空的。你可以進行一種操作x y,表示將第 x 根柱子最上面的盤子放到第 y 根柱子的最上面去。輸出不超過 10 6 次操作...

UOJ 152 盤子序列

題目描述 有n 個盤子。盤子被生產出來後,被按照某種順序摞在一起。初始盤堆中如果乙個盤子比所有它上面的盤子都大,那麼它是安全的,否則它是危險的。稱初始盤堆為a,另外有乙個開始為空的盤堆 b。為了掩蓋失誤,生產商會對盤子序列做一些 處理 每次進行以下操作中的乙個 1 將a 最上面的盤子放到 b 最上面...

漢諾塔問題解析

漢諾塔 漢諾塔 又稱河內塔 問題是源於印度乙個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片 圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動乙個圓盤。這個問題...