1. 程式人生 > 實用技巧 >約瑟夫環問題的理解

約瑟夫環問題的理解

約瑟夫環:已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。
int fun(int n, int m)
{
  int i, r = 0;
  for (i = 2; i <= n; i++)
    r = (r + m) % i;
  return r+1;
}

》》可以這樣理解這個方法:
》》當有n個人的時候,他們的編號依次是0、1、2、3、4、………、n-1。假設最後編號為x(n)的人會留下來。
》》因為數到m的那個人會出列,那麼此輪中編號為(m-1)%n的人會出列,編號為(m+0)%n的人將做為下一輪編號為0的人,此輪編號為(m+i)%n的人將做為下一輪編號為i的人…
》》因此當有n-1個人的時候,編號為i的人對應著上一輪編號為(m+i)%n的人。假設此輪編號為x(n-1)的人最終會留下來。因為編號為x(n-1)的人肯定對應著上一輪的x(n),所以有x(n)=

(m+x(n-1))%n
》》有了這個遞推公式,那我們就可以一直遞推到x(2)=(m+x(1))%2,而x(1)=0。
》》所以我們可以這麼來寫這個函式:
》》r = 0
》》for i 從 2 到 n:
》》》》r = (m+r)%i
》》最終第r個人會留下來(如果從1開始編號就是第r+1個人最終會留下來)。

參考:https://www.zhihu.com/question/20065611