josephus問題的定義如下:假設n個人排成環形,且有一正整數m<=n。從某個指定的人開始,沿環報數。每遇到第m個人就讓其出列,且報數進行下去,這個過程直到所有人都出列為止。假設m不是常數。請描述乙個o(nlgn)時間的演算法,使給定的整數n和m,輸出(n,m)-josephus排列。
解法:使用順序統計樹(order-statistic tree),順序統計樹的插入、刪除的時間複雜度為o(lgn),查詢第i大的數的時間複雜度也為o(lgn)。
偽**:
josephus(n,m)
initialize t to be empty
1. for j ← 1 to n
do create a node x with key[x] = j
os-insert(t, x)
k ← n
j ← m
2.while k > 2
do x ← os-select(root[t ], j )
print key[x]
os-delete(t, x)
k ← k − 1
j ← (( j + m − 2) mod k) + 1
3.print key[os-select(root[t ], 1)]
1.建立順序統計樹
2.先找出第j=m大的數,列印,然後從順序統計數中將其刪除,則下乙個要刪除的數為此時序列中第j+m-1大的數(序列的長度已經減小了1,所以是j+m-1而不是j+m),因為j+m-1可能大於n,所以寫成 ((j+m-2)mod k) + 1
3.列印最後乙個數
Josephus問題(約瑟夫環)
描述 有n個人坐在一圈做遊戲,給他們編號為1到n,現從1號人開始傳遞乙份烤肉,傳遞m次停下,將拿著烤肉的人從圈中退出,圈縮小,將烤肉給退出的人後面的人,然後開始繼續傳遞m次停下,又將拿著烤肉的人從圈中退出,圈縮小,依次類推,直到剩下乙個人,那個人就可以品嚐烤肉了,作程式,看看最後的獲勝者是誰?分析 ...
Josephus約瑟夫環問題
求解josephus問題 設有n個數構成乙個環鏈,現從第k個數開始數數,數到m的那個數被彈出,然後從該數的下乙個數重新開始數數,數到m的那個數又被彈出,如此重複,直到所有的數均被彈出為止。輸出這些數彈出的序列。include include define maxsize 100 typedef st...
XDOJ1009Josephus環的復仇
點我上車 題意 簡單易懂 用線段樹把陣列存起來,而且存的是順序,每次就看要拿現存陣列的第幾個然後拿就對了 比如說現在有8個,k為3 第一次拿第3個,剩7個,第二次拿第3 3 6個,剩6,第三次6 3 9 9 6 3,拿第三個,以此類推 線段樹就能很好的解決這個問題 include include i...