約瑟夫環問題

2021-09-11 07:20:43 字數 910 閱讀 1803

問題描述:已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為1的人開始報數,數到m的那個人出列;他的下乙個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。通常,我們會要求輸出最後一位出列的人的序號。

問題解法:

首先,陣列寫成以0開頭更便於計算,所以後面的分析都是以0開頭的。

1,借用模(取餘),陣列可以輕鬆表示環形。陣列 [0, 1, 2, 3, 4, 5] 可以寫成:[6%6, 7%6, 8%6, 3%6, 4%6, 5%6]. 我們把遞增的起點從第0個元素移動到第3個元素處。即實現了3,4,5,0,1,2的單調遞增。

2,把陣列 [0,1,2,3,4,5,6,7,8,9] 滾動成 [4,5,6,7,8,9,0,1,2,3]的方法: 相當於是重新把6作為基準,其他數仍然照序遞增(包括跨過陣列右界回到陣列左界,這個過程也是遞增的),所以變化方法只需要給出6如何變成0即可: (k-6)%10 , 為了保證括號裡大於零,所以額外加個模,即:(k-6+10)%10 ====> (k+4)%10.

解法一:用遞迴公式

每刪除乙個元素,就把新佇列的下標對映成規範形式(即從0開始),這樣已知最後乙個取得元素其變換後的下標必然是m,則能逆向計算出變換前的下標。

int lastnum(int n, int m)
解法二:用佇列模擬

用佇列表示環形陣列,並且模擬數數的過程。數乙個數相當於從隊首取出乙個元素,若計數沒到k,就把它放回隊尾,若到了k,就不再放回(相當於刪除掉了),並且重置計數。直到佇列剩餘1個元素。

#includeint lastnum(int n,int m) 

else

}int res = q.front();

return res;

}

約瑟夫問題 約瑟夫環

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

約瑟夫問題 約瑟夫環

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

約瑟夫環問題

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