N个人围成一圈报数,报到某一个数m的就出局,问你最后剩下来的人的号码?

算法如下:
//函数接收n和m,返回最后出圈的是第几个人
/*e.g.       yuesefu(5,2)=3
                  yuesefu(2,100)=1*/
int   yuesefu(int   n,int   m)
{
        int   i,r=0;
        for   (i=2;i <=n;i++)   r=(r+m)%i;
        return   r+1;
}

 

首先我们作一个这样的约定,
每数完一个m为一轮,
编号从0开始
每数到m之后剩下的人按数数的顺序重新开始编号
e.g,如果n=5   m=7
第1轮       第2轮       第3轮       第4轮
0123401   0123012   0120120   0101010   (编号)
1234567   1234567   1234567   1234567   (数的数字)
0123401   2340234   0230230   2323232   (如果编号一直不变则是这样)
那么第2轮中编号为0的人实际是第1轮中编号为2的人
那么第3轮中编号为0的人实际是第2轮中编号为3的人

k+1轮的编号i的人在k轮中编号为

(m%(n-k+1)+i)mod(n-k+1)
简化为
(m+i)mod(n-k+1)

e.g.
剩下来的人在最后一轮(第n-1轮)的编号为(m   mod   2+0)
那么他在倒数第二轮编号为
(m+m%2)%3

设Ak为倒数第k轮剩下来的人的编号
A1=m%2
A2=(m+A1)%3
A3=(m+A2)%4
....
Ak=(m+Ak-1)%(k+1)

那么算法就出来了

 

这就是Josephus问题
设n个人围成一圈,标号为0..n-1,从第一个人开始依次从1到k循环报数,当报到k的时候此人出圈。设J(n,   k,   i)表示第i个出圈的人的标号。

定理一:
J(n,   k,   1)   =   (k-1)   mod   n,   (n   > =   1,   k   > =   1)                           …………   (1)

证明:
由定义直接得证。 Q.E.D.

定理二:
J(n+1,k,   i+1)   =   (k   +   J(n,   k,   i))   mod   (n+1),     (n   > =   1,   k   > =   1,   1 <=   i   <=   n)   …………   (2)

证明:
设J(n,   k,   i)   =   g,因此如果有n个人,从0开始报号,第i个出圈的标号为g。现在考虑J(n+1,   k,i+1),因为J(n+1,   k,   1)   =   (k-1)   mod   (n+1),即第一步的时候删除数字(k-1)   mod   (n+1),第二步的时候从数字k开始数起。因而问题变为了找到剩下的n个数字中从k开始数起被删除的第i个数字(注意这时(k-1)   mod   (n+1)已经被删除了),而这恰好就是(g+k)   mod   (n+1),(2)成立。   Q.E.D.


根据(2),很容易求得n个数里面第i个出圈的数。


对于k   =   2,   3的情况,直接可以推导出公式来。但是对于k> =4的情况,还没有推导出公式来,目前最好的算法是一个根据估计J(n,   k,   i)上下界的快速算法。


更具体的分析,参见
[1]   Lorenz   Halbeisen,   The   Josephus   Problem,   1994
[2]   Woodhouse,   D.   ,   The   extended   Josephus   problem,   Rev.Mat.   Hisp.-Amer.(4)   33   (1973),   207-218
[3]   Robinson,   W.   J.,The   Josephus   problem,   Math.   Gazette   44   (1960),   47-52
[4]   Jakobczyk,   F.   ,   On   the   generalized   Josephus   problem,   Glasgow   Math.J.14(1973),   168-173

 

http://topic.csdn.net/t/20021110/16/1164569.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值