這是一道藍橋杯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報數,如此下去,直到所有人...