分治法:循环赛日程表问题

循环赛日程表问题问题描述:
   设有n(n = 2^k)位选手参加网球循环赛,循环赛共进行n-1天,每位选手要与其他n-1位选手比赛一场,且每位选手每天必须比赛一场,不能轮空。试按此要求为比赛安排日程:
 (1) 每个选手必须与其他n-1个选手各赛一场;
 (2) 每个选手一天只能赛一场;
 (3) 循环赛一共进行n-1天。
思路和代码比较简单,就不多解释了^_^
#include <iostream>
#include <cstdio>
using namespace std;

int K, tab[1<<4][1<<4];
void solve(){
	memset(tab, 0, sizeof(tab));
	tab[0][0] = 1;    //第一个选手
	for (int i = 1; i <= K; ++i){    //以此处理1~2、1~4、1~8选手
		int limit = 1 << (i - 1);
		for (int j = 0; j < limit; ++j) for (int k = 0; k < limit; ++k){
			tab[j + limit][k + limit] = tab[j][k];   //将左上角复制到右下角
			tab[j + limit][k] = tab[j][k] + limit;   //将左上角对应到左下角
			tab[j][k + limit] = tab[j][k] + limit;   //将左上角对应到右上角
		}
	}
}
void out(){  //输出结果
	for (int i = 0; i < (1 << K); ++i){
		for (int j = 0; j < (1 << K); ++j)
			printf("%2d ", tab[i][j]);
		cout << endl;
	}
}
int main()
{
	while (cin >> K){   //比赛选手数为2^K个
		solve();
		out();
	}
	return 0;
}


原文地址:https://www.cnblogs.com/kunsoft/p/5312691.html