約瑟夫環問題

2021-10-10 07:56:46 字數 1241 閱讀 5803

這是一道藍橋杯2023年國賽c/c++組的問題,題目是這樣的:

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

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

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

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

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

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

約定:0 < n,k < 1百萬

例如輸入:

10 3

程式應該輸出:

4模擬整個過程:建乙個bool陣列,true表示此人還活著,false表示已經自殺。這種解法的資料結構理應採用迴圈鍊錶,但是對於這道題,只需要採用一般的陣列,稍加一點迴圈鍊錶的思想,即在控制i的增加的時候,把一般的i++改為i=(i+1)%n即可。

**如下:

//約瑟夫環問題

#include

intmain()

int now=0;

int false_num=0;

//統計淘汰了幾個人

int j;

if(n==

1&&k==1)

while

(true

)//printf("now = %d\nj = %d\nnum = %d\nfalse_num = %d\n",now,j,num,false_num);}if

(false_num==n-1)

}}}}

return0;

}

這種方法時間複雜度為o(n*k)。

f(1)=0

當有2個人的時候(n=2),報道(m-1)的人自殺,最後自殺的人是誰?應該是在只有乙個人時,報數時得到的最後自殺的序號加上m,因為報到m-1的人已經自殺,只剩下2個人,另乙個自殺者就是最後自殺者,用函式表示:

f(2)=f(1)+m

可以得到遞推公式:

f(i)=f(i-1)+m

還是採用迴圈鍊錶的思想

f(i)=(f(i-1)+m)%i

有了遞推公式就可以在o(n)時間求出結果:

#include

intmain()

printf

("%d"

,result+1)

;return0;

}

2020國賽加油!

約瑟夫問題 約瑟夫環

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

約瑟夫問題 約瑟夫環

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

約瑟夫環問題

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