循环赛日程表
1. 题目:设有2k 个运动员参加循环比赛,要求如下:
(1)每个选手必须与其他选手各赛一次
(2)每个选手一天只能赛一次
(3)比赛进行n-1天
2. 分析:题目来自《计算机算法设计与分析》 P34页。书中有具体的分析,是采用分治算法来安排的赛程表。代码如下:
1 int a[100][100]={0}; 2 3 void table(int k,int a[][100]) 4 { 5 assert(k>0 && a); 6 //k=0时,只有1个人,赛程直接给出如下a[1][1]=1 7 a[1][1]=1; 8 int n=1; 9 int tmp=n; 10 for (int i=0;i<k;i++) 11 { 12 tmp=n; 13 n=n*2; 14 //填左下角 15 for (int j=tmp+1;j<=n;j++) 16 { 17 for (int k=1;k<=tmp;k++) 18 { 19 a[j][k]=a[j-tmp][k]+tmp; 20 } 21 } 22 //填右上角 23 for (int j=1;j<=tmp;j++) 24 { 25 for (int k=tmp+1;k<=n;k++) 26 { 27 a[j][k]=a[j+tmp][k-tmp]; 28 } 29 } 30 //填右下角 31 for (int j=tmp+1;j<=n;j++) 32 { 33 for (int k=tmp+1;k<=n;k++) 34 { 35 a[j][k]=a[j-tmp][k-tmp]; 36 } 37 } 38 } 39 //输出赛程表 40 for (int i=1;i<=n;i++) 41 { 42 for (int j=1;j<=n;j++) 43 { 44 cout<<a[i][j]<<" "; 45 } 46 cout<<endl; 47 } 48 }
3. 上述算法,只适应于参加选手人数是2的整数次方的情况,如果参赛选手人数为任意个,该怎样解决?这个有通用的“贝格尔”编排法,参考网站:
http://blog.sina.com.cn/s/blog_49473bb60100neks.html
http://www.java3z.com/cwbwebhome/article/article1/199.html