标签:治法 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