循环赛日程安排问题

设有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");
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_40330033/article/details/82952082