poj3517:约瑟夫问题的数学解法

约瑟夫问题:

用数学方法解的时候需要注意应当从0开始编号,因为取余会等到0解。

实质是一个递推,n个人中最终存活下来的序号与n-1个人中存活的人的序号有一个递推关系式。

分析:

假设除去第k个人。

0, 1, 2, 3, ..., k-2, k-1, k, ..., n-1  //original sequence (1)

0, 1, 2, 3, ..., k-2,      , k, ..., n-1  //get rid of kth person (2)

k, k+1, ..., n-1,    0,    1,        ..., k-2  //rearrange the sequence (3)

0, 1,     ..., n-k-1, n-k, n-k+1, ..., n-2  //the n-1 person (4)

我们假设f(n)的值为n个人中最后存活的人的序号,则

注意到(2)式(3)式(4)式其实是同一个序列。

注意(1)式和(4)式,是同一个问题,不同的仅仅是人数。

假设我们已知f(n-1),即(4)式中最后剩下的人的序号,则(3)式所对应的序号,就是f(n),即(1)式n个人中最后存活的序号。

而从(3)(4)式中我们不难发现有这样一个递推式:

f(n) = (f(n-1) + k) % n

显然,f(1) = 0。

于是递推得f(n)

代码如下:

View Code
 1 #include <stdio.h>
2
3 int main()
4 {
5 int n, k, m, i, x;
6 while (scanf("%d%d%d", &n, &k, &m) != EOF) {
7 if (n==0 && k==0 && m==0) break;
8 x = 0;
9 for (i=2; i!=n; ++i)
10 x = (x + k) % i;
11 x = (x + m) % i + 1;
12 printf("%d\n", x);
13 }
14 return 0;
15 }
posted @ 2011-09-11 19:33  alex4814  阅读(1046)  评论(0编辑  收藏  举报