问题描述:设有n=个运动员要进行网球循环赛。现在要设计一个满足以下条件的比赛日程表。

(1)每个选手必须要与其他n-1个选手各赛一次;

(2)  每个选手一天只能赛一场;

(3)  循环赛赛程是n-1天。

算法设计:设计一张循环赛日程表。

问题输入:输入k值。

问题输出:输出n×n的赛程表。

问题思路:可以采用分治递归解决,也可以采用分治非递归算法。

A. 分治递归方案

1 2 3 4 5 6 7 8
2 1 4 3 6 5 8 7
3 4 1 2 7 8 5 6
4 3 2 1 8 7 6 5
5 6 7 8 1 2 3 4
6 5 8 7 2 1 4 3
7 8 5 6 3 4 1 2
8 7 6 5 4 3 2 1

以上是一个排好的循环赛日程表。我们发现当k=1时,在这个2x2的表格里,a[0][0]=a[1][1],a[1][0]=a[0][1]。也就是对角线上的表格元素相同,当k=2时,在4x4的表格里,对角线上的2x2的小表格元素相同。随之扩展到当k=n时,在x的表格里,对角线上的2^(n-1)x2^(n-1)的小表格元素相同。也就是说,任意给定一个k值所构成的nxn的表格的元素内容,都可以直接用这个表格的前(n/2)x(n/2)上的元素去复制得到后(n/2)x(n/2)的元素,即用左上表格复制得到右下表格,左下表格得到右上表格。也就是把此问题划分成了2个子问题。且并不存在公共子问题。边界条件就是当k=0时n=1,不用执行操作。所以满足的递归方程为:

T(n)=O(1)  n=1;

T(n)=2T(n/2)+O(n^2)    n>1;

T(n)=O(n^2)。

代码如下;

#include<iostream>
#include<time.h>
using namespace std;
//分治递归
void copy(int **arr,int x1, int y1, int x2, int y2, int n)//二维数组指针
{//xiafor(int i=0;i<n;i++)for (int j = 0; j < n ; j++){arr[x2 + i][y2 + j] = arr[x1 + i][y1 + j];}
}void Table(int **arr,int x, int y, int n)
{if (n == 1)return;Table(arr,x, y, n / 2);Table(arr,x + n / 2, y, n / 2);copy(arr,x, y, x + n / 2, y + n / 2, n / 2);//copy 右下copy(arr,x + n / 2, y, x, y + n / 2, n / 2);//上
}
void print(int **arr,int n)
{for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++){cout.setf(std::ios::left);cout.width(5);cout << arr[i][j] ;}cout << endl;}
}
int main()
{int k;cout << "输入k:";cin >> k;int n = 1;for (int i = 1; i <= k; i++)n *= 2;int **arr = new int*[n];//二维数组指针初始化for (int i = 0; i < n; i++) {arr[i] = new int[n];}for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++){if (j == 0)arr[i][j] = i + 1;elsearr[i][j] = 0;}}Table(arr,0, 0, n);print(arr,n);cout << "The run time is:" << (double)clock() / CLOCKS_PER_SEC << "us" << endl;return 0;}

运行结果

B. 非递归算法

非递归算法可以先输入一列/行原始数据,通过对位copy,一步一步迭代出总方案。最坏情况下的时间复杂度为O(n^2)。

#include<iostream>
#include<cmath>
using namespace std;#define N 1024
int arr[N][N];void copy(int x1, int y1, int x2, int y2, int n)
{//xiafor (int i = 0; i < n; i++)for (int j = 0; j < n; j++){arr[x2 + i][y2 + j] = arr[x1 + i][y1 + j];}
}void Table(int k)
{int n = pow(2, k);for (int i = 0; i < n; i++)arr[i][0] = i + 1;for (int i = 2; i <= n; i *= 2){for (int j = 0; j < n; j += i){int s = i / 2;copy(j, 0, j + s, s, s);copy(j + s, 0, j, s, s);}}
}void print(int n)
{for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++){cout.setf(std::ios::left);cout.width(5);cout << arr[i][j];}cout << endl;}
}void matchtable(int k)
{int m = 1;int n = pow(2, k);for (int i = 0; i < n; i++)arr[i][0] = i + 1;for (int s = 0; s < k; s++){n /= 2;for (int t = 0; t < n; t++){for (int j = m; j < 2 * m; j++){for (int i = m; i < 2 * m; i++){arr[i - m + 2 * t*m][j] = arr[i + 2 * t*m][j - m];arr[i + 2 * t*m][j] = arr[i - m + 2 * t*m][j - m];}}}m *= 2;}
}int main()
{int k;cout << "输入k:";cin >> k;int n = pow(2, k);Table(k);print(n);cout << " 另一种" << endl;matchtable(k);print(n);return 0;
}

输出结果

算法分析与设计——2.5 循环赛日程表相关推荐

  1. 计算机算法设计与分析 循环赛日程表

    设有n=2k个运动员要进行网球循环赛.现要设计一个满足以下要求的比赛日程表:每个选手必须与其他n-1个选手各赛一次,每个选手一天只能赛一次,循环赛一共进行n-1天. 课本上的方法是从大向小推出整个日程 ...

  2. 算法设计与分析——循环赛日程表

    问题描述: 设有n=2^k个运动员要进行网球循环赛.现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次: (2)每个选手一天只能参赛一次: (3)循环赛在n-1天内结 ...

  3. 算法设计与分析----循环赛日程表

    设有n个运动员,要进行网球循环赛.现在要设计一个满足以下要求的比赛日程表(1).每个选手必须与其他n-1个选手各赛一场(2).每个选手一天只能赛一次(3).循环赛一共进行n-1天 此题一般都是用递归分 ...

  4. 基于C++的循环赛日程表算法设计

    资源下载地址:https://download.csdn.net/download/sheziqiong/86806196 资源下载地址:https://download.csdn.net/downl ...

  5. 网球循环赛 算法分析与设计(C++)

    网球循环赛 算法分析与设计(C++) 设有n个运动员要进行网球循环赛.设计一个满足以下要求的比赛日程表: 1)每个选手必须与其他n-1个选手各赛一次 2)每个选手一天只能赛一次 3)当n是偶数时,循环 ...

  6. 循环赛日程表非递归Java_王晓东《算法设计与分析》课件.ppt

    <王晓东<算法设计与分析>课件.ppt>由会员分享,可在线阅读,更多相关<王晓东<算法设计与分析>课件.ppt(356页珍藏版)>请在人人文库网上搜索. ...

  7. 循环赛日程表算法分析c语言,循环赛日程表

    该算法的核心问题是合并问题,因为把一个数分成2半,可能得到2种情况:①等分:②一组比另一组多一人:在这里我们巧妙的设计了一下,当一组比另一组多一人时,我们假设了一个虚拟选手,让他参与匹配,最后再把出现 ...

  8. 3.2.4循环赛日程表(递归与分治)

    目录 1.问题描述 2.算法分析 算法 3.摘要 参考书籍 1.问题描述 设有个运动员要进行网球循环赛. 现要设计一个满足以下要求的比赛日程表. (1)每个选手必须与其他个选手各比赛一次: (2)每个 ...

  9. 循环赛日程表算法实现

    <算法分析与设计>循环赛日程表算法 CONDITION1. 输入2的K次方支队伍,输出赛程表. CONDITION2. 考虑队伍数量不是2的K次方情况下,输出赛程表. [本题涉及算法:分治 ...

最新文章

  1. 你与ACM MM的距离只差一场算法比赛
  2. python文件操作(open()、write()、read()、readline()、readlines()、seek()、os)
  3. InstallShield 2015 生成单个EXE包和 MSI包
  4. 基于STM32F4移植W5500官方驱动库ioLibrary_Driver(转)
  5. 高性能MySQL(1)——MYSQL架构
  6. java获取当前时间星期几_java怎么获取当前日期是星期几
  7. mp3播放程序c语言,Go语言音乐播放器
  8. 人工智能的数学基础(一):绪论
  9. php/eq,thinkphp中eq标签的使用
  10. Shadow Defender影子卫士
  11. php工作p7,广告服务端PHP高级工程师(P6-P7)职位描述与岗位职责任职要求
  12. DSP TMS320F280049C之捕获eCAP(1)
  13. 百度智能云“护航”度小满金融 实现“两地三中心项目”落成
  14. Java 生成随机中文、英文姓名(下)
  15. linux系统硬盘坏道,linux系统下检测硬盘上的坏道和坏块
  16. 三亚价格最公道的婚纱摄影机构——诠释视觉婚纱摄影
  17. JAVA编程思想(二)如何面向接口编程
  18. CTF_StegSolve使用方法
  19. mysql8 rank_MySQL8.0窗口函数之排名函数(rank、dense_rank)的使用
  20. 策划,程序,美术,运营,市场,你到底有多重要?

热门文章

  1. bochs启动freedos下键盘符号乱码问题解决
  2. vs2010设置堆栈大小
  3. 为什么说python是万能的_为什么说”人生苦短,我用python“
  4. proe二次开发的第一个程序
  5. 软件架构设计原则--里氏替换原则
  6. css中的相对路径和绝对路径的问题
  7. 欧拉角、旋转矩阵及四元数
  8. xss(Cross Site Scripting)
  9. excel导入erwin数据模块
  10. ZUCC_BB平台-Quiz B-3-6-答案