赛程表安排

求n个人(n = 2k)安排循环赛的赛程表,要求任意两组都要塞一场

分治法思想:

1.将原先的问题细分为多个子问题;

2.求得子问题的解;

3.将子问题的解合并求得问题的解;

对于赛程安排,可以先以一个人为单位,两个人为一组安排比赛,之后再以之前的两个人为单位,四个人为一组安排比赛,以此类推,会发现最后的赛程表上右上角的的区域和左下角相同,右下角和左上角相同,因此,求得右边的复制左边的即可。

起点为每个区块左上角的位置,长度为当前需要安排比赛的人数。

代码如下

#include<stdio.h>
#pragma warning(disable:4996)
#define maxn 200
int d[maxn][maxn];
int n;
void dfs(int s, int num)
{
	if (2 == num)
	{
			d[s][1] = s;
		d[s][2] = s + 1;
		d[s + 1][1] = s + 1;
		d[s + 1][2] = s;
		return;
	}
	dfs(s, num / 2);
	dfs(num / 2 + s, num / 2);
	for (int i = s; i < s+num / 2; i++)
	{
		for (int j = num / 2 + 1; j <1+num; j++)
		{
			d[i][j] = d[i + num / 2][j - num / 2];
		}
	}
	for (int i = num/2+s; i <s+ num ; i++)
	{
		for (int j = num / 2 + 1; j <1+num; j++)
		{
			d[i][j] = d[i - num / 2][j - num / 2];
		}
	}
}


int main()
{
	scanf("%d", &n);
	dfs(1, n);
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
			printf("%d ",d[i][j]);
		printf("
");
	}
	getchar();
	getchar();
	return 0;
}

  

原文地址:https://www.cnblogs.com/zxzmnh/p/11622968.html