博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

约瑟夫问题

Posted on 2010-10-19 11:41  桃子在路上  阅读(289)  评论(0编辑  收藏  举报

M个人围成一圈,从第一个人开始报数,数到n的人出圈。再由下一个人开始报数,数到n的人出圈,……输出依次出圈人的编号。M值预先选定,n值由键盘输入。

[解题分析]
用一个数组存储M个人,先初始化数组,并使数组元素的值等于1,输入n的值。从1到M循环,判断该元素是否为数到n的元素,若是,则输出,并把其值赋为0,表示该元素已从数组中删除。
[算法设计]
(1) 初始化数组a[I],赋值为1。
(2) 读入n的值。
(3) for i:=1 to m do
      3.1 计数器s赋值为0;
      3.2 while s<n do
      如果j<m,则j:=j+1;否则j:=1。并且s:=s+a[j]。
(4) 输出j的值,也就是出圈人的编号。并把a[j]赋值为0;
[程序]
PROGRAM ex6(input,output);
CONST
  m=16;
VAR
  a:array[1..m] of integer;
  n,s,i,j:integer;
Begin
  {初始准备}
  for i:=1 to m do
    a[i]:=1;
  read(n);
  writeln('n=',n);
  j:=0;
  {输出m个出圈人编号}
  for i:=1 to m do
    begin
      {计数清0}
      s:=0;
      {计数为n时结束}
      while s<n do
        begin
          {处理下标}
          if j<m then j:=j+1
          else j:=1 ;
          {计数}
          s:=s+a[j]
        end;
      {输出出圈人编号}
      write(j:3);
      {该元素清0}
      a[j]:=0
   end
end.
____________________________________________
program ___;
  const m=8;
  var 

  begin
    readln(n);
    fillchar(a,sizeof(a),true);
    i:=1;
    s:=1;
    b:=m;
    repeat
      if i>m
        then i:=i mod m;
      if a[i]
         then begin
               if s mod n=0
                  then begin
                        a[i]:=false;
                        writeln(i:2);
                        b:=b-1
                      end;
                   s:=s+1;
                  end;
        i:=i+1;
    until b=0;
    readln;
  end.