51nod1073 約瑟夫環

2022-05-01 23:24:11 字數 947 閱讀 5460

解題關鍵:此題不需要模擬,可以用數學方法解決。

無論是用鍊錶實現還是用陣列實現都有乙個共同點:要模擬整個遊戲過程,不僅程式寫起來比較煩,而且時間複雜

度高達o(nm),當n,m非常大(例如上百萬,上千萬)的時候,幾乎是沒有辦法在短時間內出結果的。

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

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

。我們知道第乙個人(編號一定是m%n-1) 出列之後,剩下的n-1個人組成了乙個新的約瑟夫環(以編號為k=m%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

k-1 --> n-1

變換後就完完全全成為了(n-1)個人報數的子問題,假如我們知道這個子問題的解:例如x是最終的勝利者,那麼根

據上面這個表把這個x變回去不剛好就是n個人情況的解嗎?!!變回去的公式很簡單,相信大家都可以推出來:x=(x+k)%n

如何知道(n-1)個人報數的問題的解?對,只要知道(n-2)個人的解就行了。(n-2)個人的解呢?當然是先求(n-3)的

情況 ---- 這顯然就是乙個倒推問題!

複雜度:$o(n)$

1 #include2

using

namespace

std;

3 typedef long

long

ll;4

intmain()

10 cout<1

<11return0;

12 }

51Nod 1073 約瑟夫環

1073 約瑟夫環 題目 n個人坐成乙個圓環 編號為1 n 從第1個人開始報數,數到k的人出列,後面的人重新從1開始報數。問最後剩下的人的編號。例如 n 3,k 2。2號先出列,然後是1號,最後剩下的是3號。input 2個數n和k,表示n個人,數到k出列。2 n,k 10 6 output 最後剩...

51nod 1073 約瑟夫環

問題描述 n個人坐成乙個圓環 編號為1 n 從第1個人開始報數,數到k的人出列,後面的人重新從1開始報數。問最後剩下的人的編號。例如 n 3,k 2。2號先出列,然後是1號,最後剩下的是3號。輸入 2個數n和k,表示n個人,數到k出列。2 n,k 10 6 輸出 最後剩下的人的編號 樣例輸入 3 2...

51nod 1073 約瑟夫環

1073 約瑟夫環 基準時間限制 1 秒 空間限制 131072 kb 分值 0 難度 基礎題 n個人坐成乙個圓環 編號為1 n 從第1個人開始報數,數到k的人出列,後面的人重新從1開始報數。問最後剩下的人的編號。例如 n 3,k 2。2號先出列,然後是1號,最後剩下的是3號。input 2個數n和...