1)每个选手必须与其他n-1个选手各赛一场
2)每个选手一天只能赛一次
3)循环赛一共进行n-1天
通俗易懂地讲,就是如果你想填一个大的,你得先得出它左上角和右上角两个盒子,再沿对角线分别抄到右下角和左下角。而为了得出它左上角和右上角,就需要递归了。
为了输出n=2^k比赛日程表, 必须先有n=2^(k-1)比赛日程表,..., 依次类推,..., 而n=1 事先给定。
算法思路:
1)n=1, 直接输出 a[0][0]=1, 递归出口
2)递归调用自己arrangement(n/2)
3) 通过从左上角算出右上角,左下角,右下角
4)输出结果
具体代码如下:
const int n=8;
int a[n][n];
void merger(int n)
{
int m = n / 2;
for (int i = 0; i < m; i++)
for (int j = 0; j < m; j++)
{
a[i][j + m] = a[i][j] + m; //左上角 算出 右上角
a[i+m][j] = a[i][j + m]; 右上角 算出 左下角
a[i+m][j + m] = a[i][j]; 左上角 算出 右下角
}
}
void arrangement(int n) //调用n=2^k
{
if (n == 1) { a[0][0] = 1; return; } //递归出口
arrangement(n/2); //
merger(n); //从左上角计算出其余三个角
print_table(n); //输出
}
打印结果
void print_table(int n)
{
cout << "--------------------------\n";
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
cout << a[i][j] << "\t";
cout << endl;
}
}
因篇幅问题不能全部显示,请点此查看更多更全内容