基礎——約瑟夫環

約瑟夫環問題:一圈共有N個人,從1開始報數,報到M的人OUT,然後重新開始報數,問最後OUT的人是誰?【N=10,M=3】

/*
    ①數組:遇到一次m count+1 直到count=n  結束 / 循環n-1次 不用count計算
        / 從後往前推:
        》j = 0for i 從 2 到 n:
        》》j = (m+j)%i
        》》最終第j個人會留下來(如果從1開始編號就是第j+1個人最終會留下來。
*/
/*

    ②**遞推思想:遞推公式:可以用一個式子來表示數列{an}的第n項與它前一項或幾項的關係
**找規律**
    當有n個人時,變成一個子問題 (n-1)個人的報數問題,編號依次爲0 1 2 3 ... n-1 ,求最後一輪的人在第一輪中的編號。【對於最後一輪來說,最後留下來的人正是最後一輪開始報數的人。我們只需要求出相鄰的兩輪之間,同一個人在後一輪的編號和在前一輪裏的編號,那麼就可以求出來這個人在倒數第二輪裏的編號,求出倒數第二輪的對應編號,那麼這個人對應在倒數第三輪的也能求出……直到對應到第一輪。】

例:n=5 m=5
每一輪編號都從開始報數的那個人開始算,那麼第二輪出列的人在第二輪的編號是(m-1)%(n-1),在第一輪編號爲[m + (m - 1) % (n-1)]%n。剩下各輪也是這樣。


編號:  0 1 2 3 4      
報數人:1 2 3 4 55人 第一輪:報數爲m的人編號爲(m-1)%n,出列;
       1 2 3 44人 第二輪:有n - 1個人,編號爲(m+0)%n的開始報數
       2 3 432 4241人


so此輪編號爲(m+i)%n的人將做爲下一輪編號爲i的人;
編號爲F(n-1)的人肯定對應着上一輪的F(n) 所以有 
    F[n]=(F[n-1]+m)%n (n>1) 【F[1]=0 :剩最後一個人 此人編號爲0】

**[補充知識]**求餘、取模 區分
ex:4/3=1.3
    求餘 4/(-3)=1  商值向0方向捨棄小數位 4rem -3=1
    取模 4/(-3)=2  商值向0方向捨棄小數位爲 4mod -3=-2
    唯一的區別在於: 當x和y的正負號一樣的時候,兩個函數結果是等同的;當x和y的符號不同時,rem函數結果的符號和x的一樣,而mod和y一樣。
*/

#include<stdio.h>
int main()
{
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        int i,result=0;
        for(i=2;i<=n;i++)
            result=(result+m)%i;
        printf("%d\n",result+1);
    }
    return 0;
}
/*
    ③單向循環鏈表
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章