1066約瑟夫問題

2021-07-04 05:50:27 字數 1745 閱讀 9754

時間限制: 10 sec  

記憶體限制: 128 mb

提交: 1  

解決: 1 [

提交][

狀態][

討論版]

約瑟夫問題:有n只猴子,按順時針方向圍成一圈選大王(編號從1到n),從第1號開始報數,一直數到m,數到m的猴子退出圈外,剩下的猴子再接著從1 開始報數。就這樣,直到圈內只剩下乙隻猴子時,這個猴子就是猴王,程式設計求輸入n,m後,輸出最後猴王的編號。

每行是用空格分開的兩個整數,第乙個是 n, 第二個是 m ( 0 < m, n < 300)。最後一行是: 0 0

對於每行輸入資料(最後一行除外),輸出資料也是一行,即最後猴王的編號

6 2

12 4

8 30 0

517

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

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

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

約瑟夫環(以編號為k=m mod 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

變換後就完完全全成為了(n-1)個人報數的子問題,假如我們知道這個子問題的解:例如x是最終的勝利者,那麼根據上面這個表把這個x變回去不剛好就是n個人情況的解嗎?!!變回去的公式很簡單,相信大家都可以推出來:x'=(x+k) mod n

如何知道(n-1)個人報數的問題的解?對,只要知道(n-2)個人的解就行了。(n-2)個人的解呢?當然是先求(n-3)的情況 ---- 這顯然就是乙個倒推問題!好了,思路出來了,下面寫

遞推公式:

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

遞推公式

f[1]=0;

f=(f+m) mod i; (i>1)

有了這個公式,我們要做的就是從1-n順序算出f的數值,最後結果是f[n]。因為實際生活中編號總是從1開始,我們輸出f[n]+1

#include using namespace std;

int main()

return 0;

}

====

最一般的方法→_→
先建立乙個陣列,全部置0.
n個猴子,全部置1。count標記現在剩下多少只猴子,m_count為
開始計數,數到m就退出,也就是令其為0.
建立乙個陣列,
#includeusing namespace std;

int main()

;//用陣列標誌該位置猴子是否刪了,如果刪了置0

while (cin >> n >> m && m && n)//每次輸入資料n,m,n,m不等於0

}} for (int i = 0; i < n; i++)

if (data[i]==1)

cout << i + 1 << endl;//其實不需要迴圈了,最後只剩下乙個了,那就是猴王啦

} return 0;

}

約瑟夫問題 約瑟夫環

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

約瑟夫問題 約瑟夫環

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

約瑟夫問題

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