約瑟夫環:遞歸算法算法
假設下標從0開始,0,1,2 .. m-1共m我的,從1開始報數,報到k則此人從環出退出,問最後剩下的一我的的編號是多少?數組
如今假設m=10spa
0 1 2 3 4 5 6 7 8 9 k=3code
第一我的出列後的序列爲:blog
0 1 3 4 5 6 7 8 9遞歸
即:數學
3 4 5 6 7 8 9 0 1(*)string
咱們把該式轉化爲:it
0 1 2 3 4 5 6 7 8 (**)io
則你會發現: ((**)+3)%10則轉化爲(*)式了
也就是說,咱們求出9我的中第9次出環的編號,最後進行上面的轉換就能獲得10我的第10次出環的編號了
設f(m,k,i)爲m我的的環,報數爲k,第i我的出環的編號,則f(10,3,10)是咱們要的結果
當i=1時, f(m,k,i) = (m+k-1)%m
當i!=1時, f(m,k,i)= ( f(m-1,k,i-1)+k )%m
因此程序以下:
int fun(int m,int k,int i){ if(i==1) return (m+k-1)%m; else return (fun(m-1,k,i-1)+k)%m; } int main(int argc, char* argv[]) { for(int i=1;i<=10;i++) printf("第%2d次出環:%2d\n",i,fun(10,3,i)); return 0; }
第 1次出環: 2 第 2次出環: 5 第 3次出環: 8 第 4次出環: 1 第 5次出環: 6 第 6次出環: 0 第 7次出環: 7 第 8次出環: 4 第 9次出環: 9 第10次出環: 3
數學解(提供思路):
參考C#作法(聽說不是很好)
經常使用算法(C#): 約瑟夫環問題 約瑟夫環問題: 設有n我的圍坐在圓桌周圍,現從某個位置m(1≤m≤n)上的人開始報數,報數到k的人就站出來。 繼續下一我的,即原來的第k+1個位置上的人,又從1開始報數,再報數到k的人站出來。依此重複下去,直到所有的人都站出來爲止 using System; using System.Collections.Generic; using System.Text; namespace ExJose { class ClassJose { //從第start人開始計數,以alter爲單位循環記數出列,總人數爲total public int[] Jose(int total, int start,int alter) { int j, k = 0; //count數組存儲按出列順序的數據,以當結果返回 int[] count = new int[total + 1]; //s數組存儲初始數據 int[] s = new int[total + 1]; //對數組s賦初值,第一我的序號爲0,第二人爲1,依此下去 for (int i = 0; i < total; i++) { s[i] = i; } //按出列次序依次存於數組count中 for (int i = total; i >= 2; i--) { start = (start + alter - 1) % i; if (start == 0) start = i; count[k] = s[start]; k++; for (j = start + 1; j <= i; j++) s[j - 1] = s[j]; } count[k] = s[1]; //結果返回 return count; } static void Main(string[] args) { ClassJose e=new ClassJose (); int[] a = e.Jose(10,3,4); for (int i = 0; i < a.Length; i++) { Console.WriteLine(a[i].ToString ()); } } } }