一、问题描述:

设有n=2^{k}个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表:

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

(2)每个选手一天只能赛一次。

按此要求,可将比赛日程表设计成一个 n 行n-1列的二维表,其中,第 i 行第 j 列表示和第 i 个选手在第 j 天比赛的选手。

二、问题分析:

按照分治的策略,可将所有参赛的选手分为两部分,n=2k个选手的比赛日程表就可以通过为\frac{n}{2}=2k-1个选手设计的比赛日程表来决定。递归地执行这种分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单:只要让这2个选手进行比赛就可以了。

显然,这个求解过程是自底向上的迭代过程,其中左上角和左下角分别为选手1至选手4以及选手5至选手8前3天的比赛日程,据此,将左上角部分的所有数字按其对应位置抄到右下角,将左下角的所有数字按其对应位置抄到右上角,这样,就分别安排好了选手1至选手4以及选手5至选手8在后4天的比赛日程,如图©所示。具有多个选手的情况可以依此类推。

这种解法是把求解2^{k} 个选手比赛日程问题划分成依次求解2{1}、2{2}、…、2{k}个选手的比赛日程问题,换言之,2{k}个选手的比赛日程是在2^{k-1}个选手的比赛日程的基础上通过迭代的方法求得的。在每次迭代中,将问题划分为4部分:

(1)左上角:左上角为2^{k-1}个选手在前半程的比赛日程;

(2)左下角:左下角为另2{k-1}个选手在前半程的比赛日程,由左上角加2{k-1}得到,例如2{2}个选手比赛,左下角由左上角直接加2得到,2{3}个选手比赛,左下角由左上角直接加4得到;

(3)右上角:将左下角直接抄到右上角得到另2^{k-1}个选手在后半程的比赛日程;

(4)右下角:将左上角直接抄到右下角得到2^{k-1}个选手在后半程的比赛日程;

算法设计的关键在于寻找这4部分元素之间的对应关系。

#include <stdio.h>
#define MAX 100
int a[MAX][MAX];
void Copy(int tox,int toy,int fromx,intfromy,int r)
{for(inti=0;i<r;i++)for(intj=0;j<r;j++)a[tox+i][toy+j]=a[fromx+i][fromy+j];
}
//构造循环赛日程表,选手的数量n=2^k
void Table(int k)
{inti,r;intn=1<<k;//构造正方形表格的第一行数据for(i=0;i<n;i++)a[0][i]=i+1;//采用分治算法,构造整个循环赛程for(r=1;r<n;r<<=1)for(i=0;i<n;i+=2*r){Copy(r,r+i,0,i,r);  Copy(r,i,0,r+i,r);}printf("参赛人数为:%d\n(第i行第j列表示和第i个选手在第j天比赛的选手序号)\n",n);for(i=0;i<=n-1;i++)for(r=0;r<=n-1;r++){printf("%d ",a[i][r]);if(r==n-1)printf("\n");      }
}intmain() {     int i,r,k;int n=2^k;printf("比赛选手个数为n(n=2^k),请输入参数K(K>0):\n");scanf("%d",&k);if(k!=0)Table(k);return 0;
}

循环赛日程表算法——分治法相关推荐

  1. 循环赛日程表(分治法)

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

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

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

  3. C#内功修炼(算法)——分治法(一)

    分治法(递归的解决问题) 分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这 ...

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

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

  5. 关于算法--分治法--合并排序

    分治法: 1.思想:①将问题的实例划分为同一个问题的几个较小的实例,最好拥有相同的规模:②对于较小的实例进行求解,一般使用递归法,在问题规模足够小的情况下也是用另一个算法:③如果必要的话,合并这些较小 ...

  6. 算法--分治法归并排序 python

    设计算法 我们可以选择使用的算法设计方法有很多,插入排序使用了增量方法:在排序子数组A[1-j-1]后,将单个元素A[ j ]插入子数组的适当位置,产生排序好的子数组A[1-j]. 而这次我们将考查另 ...

  7. 跟我一起学算法——分治法

    目录 1.定义 2.适用条件分析 3.步骤 应用1:归并排序 步骤 算法 算法分析 应用2:快速排序 基本思想 算法 算法分析 参考 @ 分治法(Divide and Conquer) 1.定义 对于 ...

  8. 五大常用算法——分治法,动态规划,回溯法,分支界限法,贪心算法

    (1) 分治法 将一个难以直接解决的大问题,分割成一些规模较小的相同问题 快速排序 快排也是分治的一个实例,快排每一趟会选定一个数,将比这个数小的放左面,比这个数大的放右面, 然后递归分治求解两个子区 ...

  9. 算法导论-排序算法-分治法

    1.分治法原理 所谓的分治指的就是分而治之,即将大规模的问题分解成几个较小规模的问题.通过对较小规模问题的求解达到对整个问题的的求解.当我们将问题分解成两个较小问题求解时的分治方法就是二分法. 分支的 ...

最新文章

  1. 基于ESP32的竞赛裁判系统功能调试-硬件修改建议
  2. windows程序如何设计时间片_小程序开发要多久?制作设计小程序要多长时间?...
  3. SQL Server 2008, 2008 R2, 2012 and 2014 完全支持TLS1.2加密传输
  4. MongoDB 树形模型
  5. LSMW批处理使用方法(03)_步骤2
  6. html5画布 文本无法显示,淡出HTML5画布中的文本效果
  7. 指纹图谱相似度评价软件_不同产地佛手指纹图谱及模式识别研究
  8. 如何在 Mac 上的“快速查看”中查看和编辑文件
  9. Jquery 获取元素内容
  10. CNKI学术趋势与万方数据的知识脉络
  11. 【问题汇总】Ubuntu使用常见问题
  12. 【C++】用sort函数产生的段错误问题
  13. 结对-结对编项目作业名称-设计文档
  14. java排序链表冒泡排序_Java中的冒泡排序
  15. 自定义高效支持点击监听的RecyclerView
  16. Android Studio查看aar文件内容
  17. 清华计算机系超算团队,清华大学学生超算团队
  18. Win10(Win7)局域网设置共享文件夹,超全面步骤。
  19. 零基础CSS入门教程(30)–CSS布局实例
  20. 移动CMPP3.0短信网关接口协议

热门文章

  1. Darlin: Recursive proofs using Marlin
  2. 知识变现海哥:掌握这四个步骤,轻松实现知识变现
  3. cad编辑节点快捷键是什么_3分钟成为CAD高手,最全的快捷键命令,工作再忙必看...
  4. ditu 最简单的 中国地图
  5. python字节数组如何使用?
  6. 战网买台湾服务器物品,台湾暴雪:将于5月3日隐藏双子峰等七台服务器
  7. kafka磁盘写满处理
  8. BugKu——字符?正则?小记
  9. 「3D游戏建模」在Maya中加快建模速度的5种技巧
  10. 第五届“强网杯”全国网络安全挑战赛 - 青少年专项赛 crypto