回 帖 发 新 帖 刷新版面

主题:单循环比赛

分治例题
有n个选手的循环比赛,其中n=2^m,要求每名选手与其他n-1名选手各赛一次,每名选手每天比赛一次,比赛进行n-1天,要求每天没有选手轮空。

输入m,输出比赛安排表。

如 输入 3
   输出
1 2 3 4 5 6 7 8
2 1 4 3 6 5 8 7
3 4 1 2 7 8 5 6
4 3 2 1 8 7 6 5
5 6 7 8 1 2 3 4
6 5 8 7 2 1 4 3
7 8 5 6 3 4 1 2
8 7 6 5 4 3 2 1

回复列表 (共4个回复)

沙发

呵呵,我们刚好正在说这题
两种方法
1
var
  a:array[1..128,1..128] of integer;
  i,j,n,s,t,m,k,l:integer;
begin
  readln(m);n:=1;
  for i:=1 to m do
    n:=n*2;
  for i:=1 to n do
    a[1,i]:=i;k:=m;
  l:=n;m:=1;
  for s:=1 to k do
  begin
    l:=round(l/2);
    for t:=1 to l do
      for i:=m+1 to 2*m do
        for j:=m+1 to 2*m do
          begin
            a[i,j+(t-1)*m*2]:=a[i-m,j+(t-1)*m*2-m];
            a[i,j+(t-1)*m*2-m]:=a[i-m,j+(t-1)*m*2];
          end;
      m:=m*2;
  end;
    for i:=1 to n do
      begin
        for j:=1 to n do
          write(a[i,j]:3);
        writeln;
      end;
end.

板凳

2
  var
   a:array[1..128,1..128]of integer;
   n,m,i,j,k,t,b,i1,j1,c:integer;
  begin
   readln(m);
   n:=1;
   for i:=1 to m do n:=n*2;
 
   for i:=1 to n do a[1,i]:=i;
   
   k:=1; i:=0;
   for t:=1 to m do
     begin
       for i:=k+1 to 2*k do
         begin
           b:=0;  c:=1;
           for j:=1 to n do
             begin
               inc(b);
               if odd(c) then 
                 begin
                   i1:=i-k; j1:=j+k;
                   a[i,j]:=a[i1,j1];
                  end
               else
                 begin
                  i1:=i-k;  j1:=j-k;
                   a[i,j]:=a[i1,j1];
                 end;
               if (b mod k=0) then   inc(c);
             end;
         end;
         k:=i;
     end;
    for i:=1 to n do
        for j:=1 to n do
           begin
             write(a[i,j],' '); 
             if j=n  then writeln;
           end;
  end.
第一种是我编的,和书上的差不多,第二种是我同学编的,挺不错的

3 楼

n:=exp(m*ln(2));



如果用递归来想?

4 楼

1楼的签名档也太......厉害了点吧?

我来回复

您尚未登录,请登录后再回复。点此登录或注册