问题描述
设有n=2^k个选手参加循环赛,要求设计一个满足以下要求比赛日程表:
1)每个选手必须与其它n-1个选手各赛一次;
2)每个选手一天只能赛一次。
大概思路
构造一个n*n矩阵,矩阵的第一列元素为1…n,代表该行其他比赛选手与每一行的第一列的元素比赛。注:比如a[2][4] = 5,表示5号选手在第4-1=3天与2号选手比赛。将第一行元素初始化为1…n(其他{1,2,…n}的排列也行)。再利用分治法解决。具体思路按下不表,因为我现在只是为了记录一下自己的代码,如果有读者需要,请留言。
具体代码
核心函数
void Schedule(int n,int k){
//第一列、第一行初始化
for (int i = 1; i <= n; ++i)
a[i][1] = a[1][i] = i;
//Print(n);
int crrspndRow; // 被赋值的行号
int rowEnd; // 每一部分最后一行的行号
int internal; //每一部分的行数
for (int i = 1; i <= k; ++i){
internal = rowEnd = pow(2,i-1); // 每一部分的最后一行 从第一行到第2^(i-1)行
crrspndRow = rowEnd;
for (int row = 1; row <= rowEnd; ++row){
crrspndRow++; // 被赋值的行号++
for (int column = 1; column <= n; column++){
// 考虑赋值与被赋值之间列号的对应关系
if (((column-1)/(int)internal) %2 == 0){ //注意是 column-1
a[crrspndRow][column+internal] = a[row][column];
}
else a[crrspndRow][column-internal] = a[row][column];
}
}
}
}
其他函数
#include<iostream>
#include<cmath>
const int N = 100;
using namespace std;
int a[N][N];
void Print(int n);
void Schedule(int n,int k);
int main(){
int n = 16;
int k = 4;
Schedule(n, k);
Print(n);
return 0;
}
void Print(int n){
for(int i = 1; i <= n;++i){
for(int j = 1; j <= n; ++j){
cout << a[i][j] <<" ";
}
cout << endl;
}
}