1. 程式人生 > >迴圈賽日程安排問題

迴圈賽日程安排問題

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