約瑟夫環問題:一圈共有N個人,從1開始報數,報到M的人OUT,然後重新開始報數,問最後OUT的人是誰?【N=10,M=3】
/*
①數組:遇到一次m count+1 直到count=n 結束 / 循環n-1次 不用count計算
/ 從後往前推:
》j = 0
》for 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 5 【5人 第一輪:報數爲m的人編號爲(m-1)%n,出列;
1 2 3 4 【4人 第二輪:有n - 1個人,編號爲(m+0)%n的開始報數
2 3 4 【3人
2 4 【2人
4 【1人
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;
}
/*
③單向循環鏈表
*/