问题描述:设有n=2^k个运动员要进行网球循环赛。现在要设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其它n-1个选手各赛一次;
(2)每个选手一天只能比赛一次;
(3)循环赛一共进行n-1天。
问题分析:按曾要求可将比赛日程表设计成有n行n-1列的表。在表中第i行和第j列表示第i个选手在第j天所遇到的选手。
按照分治策略,可将所有选手对分为两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。递归地用这种一分为二的策略对选手进行分割,直到只剩下两个选手时,让这两个选手进行比赛即可。
如下图,设有n=8,则前三天的比赛左上角和左下角,分别对应后四天的比赛右下角和右上角。
#include <iostream>
using namespace std;
#define N 16
//将左上角位置(dx,dy),大小为k的二维数组的值拷贝到左上角位置(nx,ny),大小为k的区域
void Merge(int dx,int dy,int nx,int ny,int k,int a[][N])
{
for(int i=0;i<k;i+