循环赛日程表

设有 n=2^k 个运动员要进行网球循环赛。

现要设计一个满足以下要求的比赛日程表。

(1)每个选手必须与其他n-1个选手各赛一场。

(2)每个选手一天只能参赛一次。

(3)循环赛在n-1天内结束。

附上代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 //当 k=6 时,2^6=64,矩形元素的输出宽度定义为3
 4 //当 k>6 时,数组a[]的大小MAX和矩形元素的输出宽度都需要调整
 5 #define MAX 100
 6 using namespace std;
 7 int a[MAX][MAX],n;
 8 
 9 //实现方阵的复制
10 //源方阵的左上角顶点坐标(fromx,fromy),行列数为r
11 //目标方阵的左上角顶点坐标(tox,toy),行列数为r
12 void Copy(int tox,int toy,int fromx,int fromy,int r)
13 {
14     for(int i=0; i<r; i++)
15         for(int j=0; j<r; j++)
16             a[tox+i][toy+j]=a[fromx+i][fromy+j];
17 }
18 
19 //构造循环赛日程表,选手的数量n=2^k
20 void Table(int k)
21 {
22     int i,r;
23     n=1<<k;  //1<<k  ==   pow(2,k)
24     //构造正方形表格的第一行数据
25     for(i=0; i<n; i++)
26         a[0][i]=i+1;
27     //采用分治算法,构造整个循环赛日程表
28     for(r=1; r<n; r<<=1) //r<<=1    ==   r=r*2
29         for(i=0; i<n; i+=2*r)
30         {
31             Copy(r,r+i,0,i,r);
32             Copy(r,i,0,r+i,r);
33         }
34 }
35 int main()
36 {
37     int k;
38     while(~scanf("%d",&k))
39     {
40         Table(k);
41         for(int i=0; i<n; i++)
42         {
43             for(int j=0; j<n; j++)
44             {
45                 cout<<a[i][j]<<" ";
46             }
47             cout<<endl;
48         }
49     }
50     return 0;
51 }
原文地址:https://www.cnblogs.com/pshw/p/4846750.html