您的位置:首页 > 编程语言 > C语言/C++

循环赛日程表 分治&递归实现(C++)

2020-06-01 05:12 627 查看

文章目录

一、循环赛日程表问题

设有n=2^k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:

  1. 每个选手必须与其他n-1个选手各赛一次;
  2. 每个选手一天只能参赛一次;
  3. 循环赛在n-1天内结束。

分析:按此要求,我们可以将比赛日程表设计成有n行和n-1列的一个表。在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手。其中1≤i≤n,1≤j≤n-1。

  • 规划:

二、递归算法实现

// 循环赛日程表
#include<iostream>
#include<cmath>
using namespace std;

void schedule(int k, int** array);

int main()
{
int k;  // 运动员的个数n=2^k
cout << "设运动员的人数为n(n=2^k),请输入k的值:";
cin >> k;
int n = pow(2, k);  // 运动员的个数

int** array = new int* [n+1]; // 循环赛日程表
for (int i = 0;i < n+1;i++)
array[i] = new int[n+1];

schedule(k, array);

cout << "\n循环赛日程表:\n";
for (int i = 1;i <= n;i++)    // 输出二维数组
{
for (int j = 1;j <= n;j++)
cout << array[i][j] << " ";
cout << "\n";
}

// 删除二维数组
for (int i = 0;i < n + 1;i++)
delete[] array[i];
delete[] array;
return 0;
}

void schedule(int k, int** array)   // 数组下标从1开始
{
int n = 1;

for (int i = 1;i <= k;i++)  // 求总人数
n *= 2;
for (int i = 1;i <= n;i++)  // 第一行排1-8
array[1][i] = i;

int m = 1;  // 用来控制每一次填表时i行j列的起始填充位置

for (int s = 1;s <= k;s++)  // s指对称赋值的总循环次数,即分成几大步进行制作日程表
{
n = n / 2;

for (int t = 1;t <= n;t++)  //t指明内部对称赋值的循环次数
{
for (int i = m + 1;i <= 2 * m;i++) // 行
{
for (int j = m + 1;j <= 2 * m;j++) // 列
{
array[i][j + (t - 1) * m * 2] = array[i - m][j + (t - 1) * m * 2 - m];       //右上角等于左上角的值
array[i][j + (t - 1) * m * 2 - m] = array[i - m][j + (t - 1) * m * 2];       //左下角等于右上角的值
}

}

}
m *= 2;
}

}

·
·
·

*其它一些常见算法请参阅此链接~

最后,非常欢迎大家来讨论指正哦!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: