約瑟夫環問題

2022-09-19 21:30:30 字數 1562 閱讀 3549

做約瑟夫的時候被難住了一次,第一次寫部落格就拿約瑟夫開刀吧(壞笑),並且在網上找到的約瑟夫題解有些迷茫(我是演算法小zz),所以發表一下我的見解

首先認識一下什麼是約瑟夫問題:

n 個人的編號是 1~n,如果他們依編號按順時針排成乙個圓圈,從編號是1的人開始順時針報數。

(報數是從1報起)當報到 k 的時候,這個人就退出遊戲圈。下乙個人重新從1開始報數。

求最後剩下的人的編號。這就是著名的約瑟夫環問題。

本題目就是已知 n,k 的情況下,求最後剩下的人的編號。

題目的輸入是一行,2個空格分開的整數n, k

要求輸出乙個整數,表示最後剩下的人的編號。

對於這種問題,我們可以把這這個模擬成乙個圓桌,每次刪除固定的元素然後一直到只剩下乙個元素為止,在輸出這個元素

我們可以採取stl函式庫中的vector,用動態陣列解決這個問題,**如下

但是很遺憾,兩個平台都給的是tle,這是為什麼呢?

其實很容易相同,在乙個迴圈中頻繁的刪除元素,就要把這個元素的後面所有元素向後移或者前移動,多次移動就會導致效率很低,所以不得不思考別的解法;

分析一下:

對於任意的n,k;

我們可以設定f(q)為每次踢出第q個人最後的結果

0 1 2 3 4 5 6 .... n-1;

q q+1 q+2...........q-2(我們要kick off的是q+1這位兄台);

再次重複一下,將新的被殺的後乙個人作為新的0號,於是新的如下:

0 1 2 3 4 5 .......n-2;

遞推一下:

然後在想,

先是n個人玩這個遊戲,編號從0->n-1,數m退出,當第乙個m-1號人退出後,就變成了n-1個人玩這個遊戲了,將這n-1個人重新編號,如圖,會發現是由(原來的編號 - m)得到這重新編的號。那麼這時問題變成了n-1個人玩這個遊戲了,設f(n)表示n個人數m退出時問題的解,那麼f(n-1)是n-1個人數m退出時問題的解,假設f(n-1)已求出,那麼:

f( n ) = f(n - 1) + m;

並且是迴圈刪除,所以

f( n ) = (f(n - 1) + m)%n;

那麼,當得知f(n-2)的解時,反推至f(n-1)時,需要編號不超過n-1,因此等式為:

f(n-1)=(f(n-2) + m) % n-1;

那麼推廣到一般:f( n ) = (f (in- 1) + m )% n;

到最後剩下乙個人的時候直接輸出下標0就可以啦;

附上**

#includeusing

namespace

std;

int yuesefu(int n,int

m)int

main()

約瑟夫問題 約瑟夫環

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

約瑟夫問題 約瑟夫環

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

約瑟夫環問題

約瑟夫環問題 問題描述 編號是1,2,n的n個人按照順時針方向圍坐一圈,每個人持有乙個密碼 正整數 一開始任選乙個正整數作為報數上限值m,從第乙個人開始順時針方向自1開始順序報數,報到m時停止報數。報m的人出列,將他的密碼作為新的m值,從他在順時針方向的下乙個人開始重新從1報數,如此下去,直到所有人...