循环赛日程表
要求
设计一个满足以下要求的比赛日程表:
- 每个选手必须与其他n-1个选手各赛一次;
- 每个选手一天只能赛一次;
- 当n是偶数时,循环赛进行n-1天,当n是奇数时,循环赛进行n天;
举例 4位选手的循环赛日程表
蓝色部分为运动员编号。
第1行表示1号运动员第1天与2号比赛,第2天与3号比赛,第3天与4号比赛
非分治方式解决
规律
-
以6个选手为例,先写下表头。
-
从对角线往上依次填入2到6,自己打自己的情况空着。
填第一行
填完上半部分
-
空着的填入最大值6.同时同一天,谁与6比赛,6也在同一天与他比赛,故填入最大值的同时补全最后一行。
-
填完下半部分,除了最后一行。从对角线开始往下,从5到3,重复的填入最大的运动员,这里为6.
代码实现
如果是奇数的话,将运动员加1作为偶数处理,然后无论谁轮到序号最大的运动员都轮空。
所以只考虑偶数的情况。
//n为运动员数量,table为日程表
int roundRobin(int n,int** table)
{
//填右上角
for (int i = 0; i < n; i++)
for (int k = i, j = 0; k < n; k++, j++)
if (j == i)
{
//自己打自己的情况
table[j][k] = n - 1;
table[n - 1][k] = j;
}
else
table[j][k] = i;
//填左下角
for (int i = n - 2; i >= 0; i--)
for (int j = n - i - 1, k = 0; j < n-1; k++, j++)
if (j == i)
{
table[j][k] = n - 1;
table[n - 1][k] = j;
}
else
table[j][k] = i;
//填第一列
for (int i = 0; i < n