约瑟夫问题的猴子选择国王。

一、问题描述:

一堆猴子有数字,数字是1,2,3...m m .这群猴子(m)按照1-m的顺序坐成一个圈,从1开始数,每数到第n个,猴子就会离开圈,以此类推,直到圈里只剩下最后一只猴子,那么猴子就是国王。

约瑟

密码问题

问题描述:N个数字为1,2,3,...,n顺时针坐成一圈,每人拿一个密码(正整数)。从名称

编号为1的人从1开始顺时针方向报数,报数到指定编号M时停止报数,向M报数的人将出列,并将

作为新的M值,他的密码从顺时针方向的下一个人开始,从1开始往回数,以此类推,直到全部。

直到所有人都出了队列。请设计一个程序找出列表顺序,其中N≤30,m和密码值从键盘输入。

二。基本要求:

(1)输入数据:输入m,n m,n为整数,n < m

(2)中文提示按照m只猴子的方法,数N个数,猴子输出的个数是多少为王,建立一个函数实现这个函数,通过编写解决约瑟夫问题。

当m较小时,可以通过笔算求解。

M=2

也就是说,n个人组成一个圈,1,2,1,2,向2报到死亡,直到只剩下一个人。

当n = 2 k时,第一个报数的人是最后一个死的。

对于任意自然数,n可以表示为n = 2 k+t,其中t

所以t人死了,就只剩下2 k人了,这2 k人中第一个死的就是最后一个。这2 k人中第一个报数的人是2t+1。

于是我找到了M=2时约瑟夫问题的解:

求最大的2的不大于n的整数次幂,记为2 k,最后死的人是2 (n-2 k)+1。

M=3

就是n个人组成一个圈,当1,2,3,1,2,3报数到3就死了,直到只剩下一个人。

这比M=2时要复杂得多。

我们以N=2009为例。

当N=2009,M=3时,最后被杀的人记为F(2009,3),也可以简单记为F(2009)。

假设这种情况下还剩n人,下一轮会杀[n/3]人,[]表示四舍五入,还剩n-[n/3]人。

设n人为A1,A2,...,A (N-1),An。

从a1开始报数。一圈下来,剩下的人分别是A1,A2,A4,A5,...A (n-n mod 3-1),A (n-n mod 3+1),...,安。

所以你可以得到:

1.a(n-n mod 3)是本轮最后一个死的,a(n-n mod 3+1)是下一轮第一个报数的。

2.如果3|n,最后死的人是新一轮的F(n-[n/3])人。

如果n mod 3≠0且f (n-[n/3])

如果n mod 3≠0且f(n-[n/3])& gt;N mod 3,最后死的人是新回合的F(n-[n/3])-(n mod 3)人。

3.新的第K个人对应原来的3 *[(K-1)/2]+(K-1)mod 2+1个人。

综合1,2,3,我们可以得到:

F(1)=1,F(2)=2,F(3)=2,F(4)=1,F(5)=4,F(6)=1,

当f (n-[n/3])时

当f (n-[n/3])>:在n mod 3处,k=F(n-[n/3])-(n mod 3),F(n)= 3 *[(k-1)/2]+(k-1)mod 2+1。

这个算法需要计算[log(3/2)2009]次,数量不超过22,可以用笔计算。

所以:

第一圈,669人会被杀。这一圈最后一个被杀的人是2007年,剩下1340人。

第二圈,446人死亡,还剩894人。

第三圈,298人死亡,还剩596人。

第四圈198被杀,还剩398人。

第五圈132人阵亡,还剩266人。

第六圈杀了88人,剩下178人。

第七圈杀了59人,剩下119人。

第八圈,39人死亡,还剩80人。

第九圈,26人被杀,还剩54人。

第十圈18被杀,还剩36人。

十一圈,杀了12人,剩下24人。

十二圈,杀了8个人,剩下16个人。

十三圈,杀5人,剩下11人。

十四圈,死了三个人,剩下八个人。

十五圈,死了两个,还剩六个。

F(1)=1,F(2)=2,F(3)=2,F(4)=1,F(5)=4,F(6)=1,

然后推回去。

F(8)= 7 F(11)= 7 F(16)= 8 F(24)= 11 F(36)= 16 F(54)= 23 F(80)= 31 F(119)= 43 F(178

F(596)= 191 F(894)= 286 F(1340)= 425 F(2009)= 634