猴子选大王
【问题】n只猴子选大王,选举办法如下:从头到尾1,2,3报数,凡报3的退出,余下的从尾到头1,2,3报数,凡报3的退出...如此类推,当剩下两只猴子时,取这时报1的为王,若想当猴王,请问当初应占据什么位置?
【测试数据】
n │7
│10│20│100 │
──┼─┼─┼─┼──┼
位置│2
│ 8│16│ 77 │
【参考程序1】
const number=3;
var n,num,i,total:integer;
a:array[1..100]of
boolean; order:boolean;
begin
writeln('input
n:');
readln(n);
total:=n;
{队伍中剩下的猴子数}
for i:=1
to n do a[i]:=true;
repeat
order:=true;
{order=true:顺序报数}
num:=0;
{num:报的数字}
for
i:=1 to n do {顺序报数}
if a[i] then begin {第i只在队列中才有资格报数}
num:=num+1;
if (num=number)
then begin
{如果为3}
a[i]:=false;total:=total-1;
{出队,且猴子数少1}
num:=0;
{num置0,又准备从1报起}
end;
end;
{报到尾}
if
total>number-1 then order:=false;
{如还要继续报,则从尾到头}
num:=0;
{从尾到头时,order=false}
for
i:=n downto 1 do {逆向报数}
if a[i] then begin {在队列中}
num:=num+1;
if (num=number)
then begin
a[i]:=false;total:=total-1;
num:=0;
end;
end;
until
total=number-1; {直到剩下2只}
if not
order then for i:=1 to n do if a[i] then begin
{报剩2只时,如上一次为从尾到头报数,则猴王为从头到尾报的第一只}
writeln('The Monkey King is :',i);readln;halt;end;
if
order then for i:=n
downto 1 do if a[i] then begin
{报剩2只时,如上一次为从头到尾报数,则猴王为从尾到头报的第一只}
writeln('The Monkey King is :',i);readln;halt;end;
end.
【参考程序2】
程序1中,用了order来记录是顺序还是逆序报数,不太方便。
现简化之,取消了order,而在每一次报数前都判断是否只剩2只。
const number=3;
var
n,num,i,total:integer; a:array[1..200]of boolean;
begin
writeln('input n:');
readln(n);
total:=n;
for i:=1 to n do a[i]:=true;
repeat
num:=0;
for i:=1 to n do
if a[i] then begin
if
total=2 then begin writeln('he is :',i); readln;halt;end;
num:=num+1;
if
(num=number) then
begin
a[i]:=false;total:=total-1;
num:=0;
end;
end;
num:=0;
for i:=n downto 1 do
if a[i] then begin
if
total=2 then begin writeln('he is :',i); readln; halt;end;
num:=num+1;
if
(num=number) then
begin
a[i]:=false;total:=total-1;
num:=0;
end;
end;
until total<number-1;
end.
狐狸捉兔子
【问题】围绕着山顶有10个洞,狐狸要吃兔子,兔子说:“可以,但必须找到我,我就藏身于这十个洞中,你从10号洞出发,先到1号洞找,第二次隔1个洞找,第三次隔2个洞找,以后如此类推,次数不限。”但狐狸从早到晚进进出出了1000次,仍没有找到兔子。问兔子究竟藏在哪个洞里?
【答案】2,4,7,9
【参考程序1】
【参考程序2】
const
const
holenumber=10;
m=10; {洞数}
var
var
hole:array[0..holenumber]
l,f,t:integer;
of 0..1;
a:array[1..m+1] of 0..1;
step,i,number:longint;
begin
begin
for t:=1 to m do
for i:=0 to 9
do hole[i]:=0;
a[t]:=0;
number:=0;
f:=0; t:=0; l:=0;
for step:=1 to 1000 do begin
repeat
number:=number+step; {循环地数}
l:=l+1; {隔几个洞}
i:=number mod holenumber; {第几个洞}
t:=t+l; {第几个洞}
hole[i]:=1;
if t>m+1 then t:=t mod m;
end;
if t=0 then t:=10;{循环地找}
for i:=0 to holenumber-1 do
a[t]:=1;{该洞已进过}
if hole[i]=0 then write(i:3);
f:=f+1; {进洞的次数}
readln;
until f=1000;
end.
for t:=1 to 10 do
if a[t]=0 then write(t,' ');
readln
end.