約瑟夫環問題(數論)

2021-07-11 14:54:22 字數 1746 閱讀 5634



約瑟夫環問題描述: n

個人圍成一圈(編號分別為1-n),從某人開始順序報號1,2,3…m凡報到m者的人出列,再接著從下乙個人開始數,輸出最終出列的人的編號。

(約瑟夫環是乙個數學的應用問題:已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下乙個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。)

輸入總人數n,接著輸入乙個整數k和m,前者表示從第k人開始數,後者表示每次數到m的人出列,(n,k,m之間均用空格隔開,  1 <= k <= n <= 10000)

sample input

5 2 3

7 1 3

sample output54

上述方法的效率很低,其時間複雜度為o(mn)。當n和m很大時,很難在短時間內得出結果。不過好處就是可以給出n個人出圈的次序。只要在刪除前儲存一下即可。

下面利用數學推導,如果能得出乙個通式,就可以利用遞迴、迴圈等手段解決。下面給出推導的過程:

(1)第乙個被刪除的數為 (m - 1) % n。

(2)假設第二輪的開始數字為k,那麼這n - 1個數構成的約瑟夫環為k, k + 1, k + 2, k +3, .....,k - 3, k - 2。做乙個簡單的對映。

k         ----->  0 

k+1    ------> 1 

k+2    ------> 2 

... 

... 

k-2    ------>  n-2 

這是乙個n -1個人的問題,如果能從n - 1個人問題的解推出 n 個人問題的解,從而得到乙個遞推公式,那麼問題就解決了。假如我們已經知道了n -1個人時,最後勝利者的編號為x,利用對映關係逆推,就可以得出n個人時,勝利者的編號為 (x + k) % n。其中k等於m % n。代入(x + k) % n  <=>  (x + (m % n))%n <=> (x%n + (m%n)%n)%n <=> (x%n+m%n)%n <=> (x+m)%n

(3)第二個被刪除的數為(m - 1) % (n - 1)。

(4)假設第三輪的開始數字為o,那麼這n - 2個數構成的約瑟夫環為o, o + 1, o + 2,......o - 3, o - 2.。繼續做對映。

o         ----->  0 

o+1    ------> 1 

o+2    ------> 2 

... 

... 

o-2     ------>  n-3 

這是乙個n - 2個人的問題。假設最後的勝利者為y,那麼n -1個人時,勝利者為 (y + o) % (n -1 ),其中o等於m % (n -1 )。代入可得 (y+m) % (n-1)

要得到n - 1個人問題的解,只需得到n - 2個人問題的解,倒推下去。只有乙個人時,勝利者就是編號0。下面給出遞推式:

f [1] = 0; 

f [ i ] = ( f [i -1] + m) % i; (i>1) 

第二種方法:根據以上推出的結論

ac**:

#include

using namespace std;

int solution(int n, int m) 

int main(void)

{int n,m,t;//n表示總人數,m表示間隔人數,t表示起始人的序號

cin>>n>>m>>t;

cout<<(solution(n,m)+t-1)%n+1<

約瑟夫問題 約瑟夫環

約瑟夫 問題 有時也稱為約瑟夫斯置換,是乙個出現在電腦科學和數學中的問題。在計算機程式設計的演算法中,類似問題又稱為約瑟夫環。又稱 丟手絹問題 據說著名猶太歷史學家 josephus有過以下的故事 在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死...

約瑟夫問題 約瑟夫環

約瑟夫問題 有時也稱為約瑟夫斯置換,是乙個出現在電腦科學和數學中的問題。在計算機程式設計的演算法中,類似問題又稱為約瑟夫環。又稱 丟手絹問題 據說著名猶太歷史學家 josephus有過以下的故事 在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死也...

數論三 約瑟夫問題

描述 小hi和小ho的班級正在進行班長的選舉,他們決定通過一種特殊的方式來選擇班長。首先n個候選人圍成乙個圈,依次編號為0.n 1。然後隨機抽選乙個數k,並0號候選人開始按從1到k的順序依次報數,n 1號候選人報數之後,又再次從0開始。當有人報到k時,這個人被淘汰,從圈裡出去。下乙個人從1開始重新報...