史上最全的約瑟夫環演算法程式和原理

2021-08-25 04:47:30 字數 2456 閱讀 4008

數學演算法:

#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輸出該數值,直至全部輸出。分析 該題目的通用解法是利用迴圈鍊錶,當然也可以利用迴圈陣列。易於擴充套件的做法是,定義迴圈鍊錶的資料結構,並實現迴圈鍊錶的基本操作,利用這些基本操作如插入 刪除 初始化 構建鍊錶等操作 簡易的實現方法則是僅適合該...