码迷,mamicode.com
首页 > 其他好文 > 详细

赛程表安排

时间:2019-10-04 21:20:30      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:治法   clu   要求   右上角   长度   int   起点   printf   i++   

求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("\n");
	}
	getchar();
	getchar();
	return 0;
}

  

赛程表安排

标签:治法   clu   要求   右上角   长度   int   起点   printf   i++   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!