设有 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 }