约瑟夫问题的数学解法
2013-11-08 15:49
441 查看
问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。
第一轮:
编号: 0, 1, 2, ...m-2,m-1,m,m+1.... n-1
在报数之后,m-1 退出
编号: 0,1,2,.....m-2,m,m+1,....n-1
第二轮(人未退出):
轮到 m 开始报数,此时报数序列如下:
(式1)编号:m,m+1,....0,1,2...n-1.....m-2
对这个序列重新编号
(式2)编号:0,1,2.....n-2
由式2的编号x 计算 式1的编号 x‘ 可用此公式:
x = (x' + m)% N N 为当前环中人数加1
ps:我不知道这个公式如何得出的
也就是说,如果已知 第i轮某个人的编号为x,则可以计算出 第i-1轮他的编号,此处的编号为每一轮的编号都是从 0-n-1 重新编号过的编号(下同)。
可见第n轮只剩下一个人的编号为 0 此人即为胜利者
那么 第n-1轮 胜利者的编号为 (0+m)%2
以此类推可的 第一轮胜利者的编号,即原始编号
代码如下:
第一轮:
编号: 0, 1, 2, ...m-2,m-1,m,m+1.... n-1
在报数之后,m-1 退出
编号: 0,1,2,.....m-2,m,m+1,....n-1
第二轮(人未退出):
轮到 m 开始报数,此时报数序列如下:
(式1)编号:m,m+1,....0,1,2...n-1.....m-2
对这个序列重新编号
(式2)编号:0,1,2.....n-2
由式2的编号x 计算 式1的编号 x‘ 可用此公式:
x = (x' + m)% N N 为当前环中人数加1
ps:我不知道这个公式如何得出的
也就是说,如果已知 第i轮某个人的编号为x,则可以计算出 第i-1轮他的编号,此处的编号为每一轮的编号都是从 0-n-1 重新编号过的编号(下同)。
可见第n轮只剩下一个人的编号为 0 此人即为胜利者
那么 第n-1轮 胜利者的编号为 (0+m)%2
以此类推可的 第一轮胜利者的编号,即原始编号
代码如下:
#include <stdio.h> int main(void) { int i,s = 0; int m = 3; int n = 20; for(i=2; i<=n; i++){ s = (s+m)%i; } printf("%d\n", s); return 0; }