设有n=2k个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能赛一次。
按此要求,可将比赛日程表设计成一个 n 行n-1列的二维表,其中,第 i 行第 j 列表示和第 i 个选手在第 j 天比赛的选手。
按照分治的策略,可将所有参赛的选手分为两部分,n=2k个选手的比赛日程表就可以通过为n/2=2k-1个选手设计的比赛日程表来决定。递归地执行这种分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单:只要让这2个选手进行比赛就可以了。
#include <stdio.h>
using namespace std;
#define MAX 100
int a[MAX][MAX];
void GameTable(int k)
{
int n = 2;
a[1][1] = 1;
a[1][2] = 2;
a[2][1] = 2;
a[2][2] = 1;
for (int t = 1; t < k; t++)
{
int temp = n;
n = n*2;
//填左下角元素
for (int i = temp+1; i <= n; i++)
{
for (int j = 0; j <= temp; j++)
{
a[i][j] = a[i-temp][j] + temp;
}
}
//填右上角元素
for (int i = 1; i <= temp; i++)
{
for (int j = temp+1; j <= n; j++)
{
a[i][j] = a[i+temp][(j+temp)%n];
}
}
//填右下角元素
for (int i = temp+1; i <= n; i++)
{
for (int j = temp+1; j <= n; j++)
{
a[i][j] = a[i-temp][j-temp];
}
}
}
}
int main()
{
int k = 4;
GameTable(k);
for (int i = 1; i <= 6; i++)
{
for (int j = 1; j <= 6; j++)
{
printf("%i",a[i][j]);
printf(" ");
}
printf("\n");
}
}