scm高达:pascal 约瑟夫问题

来源:百度文库 编辑:中科新闻网 时间:2024/05/01 02:00:00
var a:array[1..8] of 0..1;
i,k,j,t:integer;
begin
k:=6;
for i:=1 to 8 do
begin
a[i]:=1;
{write(a[i],' ');}
end;
j:=0;
i:=0;
repeat
i:=i+k;
if i>8 then i:=i mod 8;
if a[i]=1 then begin writeln(i); a[i]:=0; j:=j+1; end
else
repeat
i:=i+1;
if a[i]=1 then begin writeln(i); a[i]:=0; j:=j+1; t:=1; end;
until t=1;
until j=8;
end.
有什么不对吗?帮忙改正!

你觉得你写的是这个例子:8个人,从1数到6,叫6的人就走,依次输出走的顺序,对吧?
你的程序有3大问题:
1.你只考虑到隔着的第六个位置是否有人,无则向后推,直到遇到第1个有人的,就认为他是报6的。算是对了1半。问题是,这六个位置中的其他位置是否为空呢??完全有这种可能,你就是忽略了这个问题。这是你的程序的最大弊病。
2.你在行文的时候,第2个repeat中的t,你没有给它初始化,这样的话,如果系统给他的初始就是t=1,那不是白搭?即使不是t=1,第1次满足if条件,你给他附值了,t=1,其他部分没有给他更改的余地,那下一次进入该循环时,即使不符合你的if条件,t一样是=1,循环就会结束。此为第二个问题。
3.同样是第二个repeat,之前你会考虑i>8的情况,为什么就不在这里考虑呢?这应该是你的一时大意吧```
好了,以下是我做这个例子的程序,给你作参考,同样是8人报6数。不是最优,但能完成这一任务。
var i,j,rs,tou:integer;
a:array[1..8]of 0..1;
begin
for i:=1 to 8 do
a[i]:=1;
rs:=0;
tou:=0;
i:=0;
repeat
inc(tou);
if tou>8 then tou:=1;
if a[tou]=1 then inc(i);
if i=6 then
begin
write(tou,' ');
i:=0;
a[tou]:=0;
inc(rs);
end;
until rs=7;
tou:=1;
while a[tou]<>1 do
inc(tou);
writeln(tou);
end.

约瑟夫问题是数据结构中循环对列应用的典行例子.

var a:array[1..10000]of integer;
m,n,i,j,s:integer;
begin
readln(m,n);for i:=1 to m do a[i]:=1;
i:=0;s:=0;j:=0;
repeat
i:=i+1;if i>m then i:=1;if a[i]=1 then begin s:=s+1;
if s=n then begin a[i]:=0; writeln(i);j:=j+1;s:=0;
end;end;
until j=m
end.
这是最简洁的方法,猴子选大王问题。
end.