數學演算法:
#include "stdio.h"
#include "stdlib.h"
int josephus(int n, int m)
else
return pos;
}int josephus_no_recurse_1(int n, int m)
return s + 1;
}int josephus_no_recurse_2(int n, int m)
}return s;
} 我們需要對f[n]=(f[n-1]+k)%n式進行修正:
f[n]=(f[n-1]+k)%n;if(f[n]==0)f[n]=n;
測試時發現:需不需要修正是根據情況而定的--josephus_no_recurse_1這種不需要
*/int main()
模擬演算法:
#include
#define max_count 300
int main()
printf("pls input a loop count:/n");
scanf("%d", &m);
printf("n:%d, m:%d/n", n, m);
for (i=0; i
鍊錶演算法:
#include "stdio.h"
#include "stdlib.h"
struct node node;
int main()
else
}last->next = first; // make the link to be a loop link
count = 1;
while (first != null)
if (count == m-1)
++count;
first = first->next;
}return 0;
}首先一開始的序列
序列 1 : 1, 2, 3, 4, …, n-2, n-1, n
此時出佇列的第乙個人,位置為 k , 號碼肯定是 m%n 。這個應該沒有問題,也就是取餘操作使得陣列類似能夠有循 環的功能。
此時序列 2 : 1, 2, 3, 4, … k-1, k+1, …, n-2, n-1, n
此時 k出佇列,序列2中為n-1個人了。
根據序列 2 , 得到序列 3 :
k+1, k+2, k+3, …, n-2, n-1, n, 1, 2, 3,…, k-2, k-1
從序列2得到序列3很簡單,也就是將k+1作為 開始,然後將1連到n的後面,其實只是位置的不同,但是本質兩個序列是一樣的。所以同樣,這裡也是n-1個元素。
序列3可以對映得到序列4:
這裡我就亂掉了,這個對映是可以做,但是對映關係 是怎樣的?
ok,先不管對映關係, 我們繼續來推導。
對於序列4,我們 假設能夠得到解,也就是最後乙個退出的人的號碼,設定為x。如果我們能夠通過對映關係,將x在序列3中對應的號碼x』求出來,那我們就可以得到序列3的 解,因為序列3其實和序列2是同乙個,所以序列2的解我們也就得到了,序列2就是序列1去掉乙個k,這個k對於序列1的解沒有任何影響,所以序列1的答案 就是求出來的x』。
那關鍵就是如何 通過x得到x』 ,也就是對映關係的問題。
對於序列4,如果我們要得到1到n-1序列中的值,我們也是做取餘操作,只不過除數變為n-1了。
但是如何得到關係為 x'=(x+m)%n,從而得到遞推式
f(i)=(f(i-1)+m)%i
還是沒法理解出來
在編號第乙個人(編號是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個人情況的解嗎?
變回去的公式很簡單,
1 對應k+1 2對應k+2……x對應k+x(如上面對應轉換)
所以x`=x+k
但當x`
x『=(x+k)%n,由此,我們可以得到乙個遞推公式
f[1]=1
f[n]=(f[n-1]+k)%n (n>1)
如果你認為上式可以推出約瑟夫環問題的解,很不幸,你錯了,上面的遞推公式中,在某種情況 下,f[n-1]+k會整除n,如n=2,k=3,這時我們修要對上式進行修正,
f[n]=(f[n-1]+k)%n;if(f[n]==0)f[n]=n;
問題得解
還沒看的:
約瑟夫環的O n 演算法
問題描述 已知n個人 以編號1,2,3.n分別表示 圍坐在一張圓桌周圍。從編號為1的人開始報數,數到m的那個人出列 他的下乙個人又從1開始報數,數到m的那個人又出列 依此規律重複下去,直到圓桌周圍的人全部出列,求最後乙個出列人的編號。為了討論方便,先把問題稍微改變一下,並不影響原意 問題描述 n個人...
約瑟夫環O N 和O M N 演算法詳解
問題描述 已知n個人 以編號1,2,3 n分別表示 圍坐在一張圓桌周圍。從編號為1的人開始報數,數到m的那個人出列 他的下乙個人又從1開始報數,數到m的那個人又出列 依此規律重複下去,直到圓桌周圍的人全部出列,求最後乙個出列人的編號。該問題可以用陣列或者迴圈鍊錶模擬,因為都是直接模擬,需要迴圈n次,...
演算法 約瑟夫環的簡易實現
題目 使用者輸入m,n值,從1至n開始順序迴圈數數,每數到m輸出該數值,直至全部輸出。分析 該題目的通用解法是利用迴圈鍊錶,當然也可以利用迴圈陣列。易於擴充套件的做法是,定義迴圈鍊錶的資料結構,並實現迴圈鍊錶的基本操作,利用這些基本操作如插入 刪除 初始化 構建鍊錶等操作 簡易的實現方法則是僅適合該...