約瑟夫問題

2021-07-10 10:14:35 字數 1469 閱讀 1241

網上的解釋感覺思維跳躍太大 糾結好久  現在記錄一下我的**思路

先附上搜狗百科的解釋(網上都是這個版本一點創新都沒有 — —!)

如果只求最後乙個報數勝利者的話,我們可以用數學歸納法解決該問題,為了討

論方便,先把問題稍微改變一下,並不影響原意:

問題描述:n個人(編號0~(n-1)),從0開始報數,報到(m-1)的退出,剩下的人

繼續從0開始報數。求勝利者的編號。

我們知道第乙個人(編號一定是m%n-1) 出列之後,剩下的n-1個人組成了乙個新

的約瑟夫環(以編號為k=m%n的人開始):

k  k+1  k+2  ... n-2, n-1, 0, 1, 2, ... k-2並且從k開始報0。

現在我們把他們的編號做一下轉換:

k     --> 0

k+1   --> 1

k+2   --> 2

......

k-2   --> n-2

k-1   --> n-1

變換後就完完全全成為了(n-1)個人報數的子問題,假如我們知道這個子問題的解:

例如x是最終的勝利者,那麼根據上面這個表把這個x變回去不剛好就是n個人情

令f[i]表示i個人玩遊戲報m退出最後勝利者的編號,最後的結果自然是f[n]。

遞推公式

f[1]=0;

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

有了這個公式,我們要做的就是從1-n順序算出f[i]的數值,最後結果是f[n]。

因為實際生活中編號總是從1開始,我們輸出f[n]+1。

下面是我的**

int fun(int n,int m)      //n是人數 m是需要報數的個數

理解上面**最重要的一點是:

如果知道知道去除乙個倒霉蛋之後 的陣列中最後勝利的人的位置     (一定會知道的 應為遞迴到最後陣列只有乙個元素)

那麼他在去除乙個倒霉蛋之前的陣列中的位置是多少呢?

假設去除倒霉蛋之後要從k開始計數(0到m-1)

令k的起始位置為0  k+x的位置是最後勝出的人

可以很容易得出在去除倒霉蛋之前的陣列裡k的位置為m%n(從0開始  倒霉蛋的位置是m%n-1)

由於k+x的位置是最後勝出的人 而且 k=m%n

所以去除倒霉蛋之前的陣列裡x的位置是m%n+x (x在去除倒霉蛋之前的陣列裡總的偏移量)

m%n+x這個值可能會大於n  所以

去除倒霉蛋之前的陣列裡x的位置是(m%n+x)%n

我們寫的函式的返回值是當前陣列中勝利者的位置(從0開始)  所以

x=fun(n-1,m);       //去除乙個倒霉蛋之後 的陣列中最後勝利的人的位置    起始位置為0
調整一下位置就得到

(fun(n-1,m)+m%n)%n

約瑟夫問題 約瑟夫環

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

約瑟夫問題 約瑟夫環

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

約瑟夫問題

這是17世紀的法國數學家加斯帕在 數目的遊戲問題 中講的乙個故事 15個教徒和15 個非教徒在深海上遇險,必須將一半的人投入海中,其餘的人才能倖免於難,於是想了乙個辦法 30個人圍成一圓圈,從第乙個人開始依次報數,每數到第九個人就將他扔入大海,如此迴圈進行直到僅餘15個人為止。問怎樣排法,才能使每次...