|| 返回 || 本站首页 ||奥赛信息||计算机基础||pascal基础||数据结构||经典算法||试题汇编||校本教程||自主练习||

|| 自主练习>> 猴子选大王、狐狸捉兔子

双击自动滚屏 

   

猴子选大王

【问题】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.


 
 

 

 
 
 

制作与维护:重庆市忠县中学 谭海