约瑟夫问题(编程求解)
var
k:longint;
i,j,m,s:longint;
begin
readln(k);
for m:=2 to 9999999 do
begin
i:=2*k;
j:=0;
s:=1;
while i>k do
begin
j:=(j+m) mod i;
if j=0 then j:=i;
if j<=k then begin s:=0;break; end;
dec(i);
dec(j);
end;
if s=1 then begin writeln(m);halt; end;
end;
end.
经典数学故事之约瑟夫问题
有一个古老的传说,有64名战士被敌人俘虏了,敌人命令它们排成一个圈,编上号码1,2,3,……64。敌人把1号杀了,又把3号杀了,他们是隔一个杀一个这样转着圈杀。最后剩下一个人,这个人就是约瑟夫,请问约瑟夫是多少号?
这就是数学上有名的“约瑟夫问题”。给大家一个提示,敌人从l号开始,隔一个杀一个,第一圈把奇数号码的战士全杀死了。剩下的32名战士需要重新编号,而敌人在第二圈杀死的是重新编排的奇数号码。按照这个思路,看看你能不能解决这个问题?
答案解析:
由于第一圈剩下的全部是偶数号2,4,6,8,……64。把它们全部用2除,得1,2,3,4,……32.这是第二圈重新编的号码。第二圈杀过之后,又把奇数号码都杀掉了,还剩下16个人。如此下去,可以想到最后剩下的必然是64号。
64=2×2×2×2×2×2,它可以连续被2整除6次,是从1到64中质因数里2最多的数,因此,最后必然把64号剩下。从64=2×2×2×2×2×2还可以看到,是转过6圈之后,把约瑟夫斯剩下来的。