新约瑟夫问题

【问题描述】(newnumber.pas/c/cpp)

1MM个自然数按由小到大的顺序沿顺时针围成一圈。以S为起点,先沿顺时针方向数到第N个数就出圈,然后再沿逆时针方向数到第K个数再出圈,再沿顺时针方向数到第N个数就出圈,然后再沿逆时针方向数到第K个数再出圈,……。这样按顺时针方向和逆时针方向不断出圈,直到全部数出完圈为止。打印先后出圈的数的序列0。

【输入格式】newnumber.in

文件中共4行,每行为1个自然数,分别表示题目中的MSNKM不超过1000

【输出格式】newnumber.out

仅一行,先后出圈的序列,每个数字之间有一个空格。

【样例输入】

       8

       1

       3

       2

【样例输出】

       3 1 5 2 7 4 6 8

(解释:先从1开始沿顺时针方向数到3,所以3先出圈;再从2开始沿逆时针方向数到1,所以1出圈;再从2开始沿顺时针方向数到5,所以5出圈;再从4开始沿逆时针方向数到2,所以2出圈,……

 

 

 

代码
type
    xx
=record
    l,r:integer;
    
end;
var m,s,n,k,i,j,sum:integer;
    a:
array [1..1000of xx;

begin
assign(input,
'newnumber.in'); reset(input);
assign(output,
'newnumber.out'); rewrite(output);
readln(m);
readln(s);
readln(n);
readln(k);
for i:=2 to m-1 do  {做好链表,每个元素的左右相邻位置}
   
begin
   a[i].l:
=i-1;

   a[i].r:
=i+1;

   
end;
a[
1].l:=m;a[1].r:=2;{特殊情况}
a[m].l:
=m-1;a[m].r:=1;
sum:
=m;{计数}
j:
=a[s].l;{指针元素位置}
while sum>0 do
  
begin
      
for i:=1 to n do  {右移}
         j:
=a[j].r;
       
if sum=1 then  write(j) else write(j,' ');
      a[a[j].l].r:
=a[j].r;{改变链表,注意a[a[j].l].r的运用}
      a[a[j].r].l:
=a[j].l;
      sum:
=sum-1;      if sum=0 then exit;
      
for i:=1 to k do{左移}
          j:
=a[j].l;
      
if sum=1 then write(j) else write(j,' ');
           a[a[j].l].r:
=a[j].r;
      a[a[j].r].l:
=a[j].l; 
      sum:
=sum-1;
  
end;
close(input); close(output);
end.

 

 

posted @ 2010-04-08 09:50  jesonpeng  阅读(487)  评论(0编辑  收藏  举报