分治法-循环赛日程表问题
问题描述:
- 设有n=2^k个运动员,要进行网球循环赛。
- 每个选手必须与其他n-1个选手各赛一次。
- 每个选手一天只能赛一次。
- 循环赛一共进行n-1天。
算法策略:
1、将所有的选手分为两半,n个选手的比赛日程表可以通过为n/2个选手设计的比赛日程表来决定。
2、递归地用对选手进行分割,直到只剩下2个选手时,只要让这2个选手进行比赛就可以了。
(1)当k=1时,即人数为2人,此时表为
1 2
2 1
解释:如果只有两个选手,那么第0列看作选手编号(从0开始对列编号,第0列可以看作每个选手第0天在和自己打),第1列就是在第一天,每个选手的对手编号。
(2)当k=2时,人数为4人,循环表为
1 2 3 4
2 1 4 3
3 4 1 2
4 3 2 1
解释:如果有4个选手,分别设计4/2=2个比赛日程表,1-2选手前一天的比赛日程表如上图左上角的部分,3-4选手前一天的比赛日程表如上图左下角的部分。据此,后两天的日程表可以将左上角的子表按其对应位置抄到右下角的子表,左下角的子表可以按其对应位置抄到右上角的子表。
表的行列长度均为参赛选手数2^2 = 4,在用分治法求行、列长度均为(2^2)/2=2的子表时,首先确定左上角的子表,左下角的子表可以由左上角的子表加(2^2)/2=2得到。
(3)当k=3时,人数为8人,此时循环表为
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
解释:选手人数为8时,左上角的子表是选手1至选手4的前三天的比赛日程,左下角的子表是选手5至选手8前三天的比赛日程。据此后四天的比赛日程,就是分别将左上角子表按其对应位置抄到右下角的子表,将左下角的子表按其对应位置抄到右上角的子表。这样就完成了比赛日程的安排。
小结:在每次迭代求解的过程中,可以看作4部分:
1)求左上角子表:左上角子表是前个选手的比赛前半程的比赛日程。
2)求左下角子表:左下角子表是剩余的个选手的比赛前半程比赛日程。这个子表和左上角子表的对应关系式为:对应元素等于左上角子表对应元素加 。
3)求右上角子表:等于左下角子表的对应元素。
4)求右下角子表:等于左上角子表的对应元素。
具体的实现代码(java实现):
import java.util.Scanner;public class Main {public static int[][] table(int n) {int[][] a = new int[n][n];//构造赛程表第一行数据for (int i = 0; i < n; i++)a[0][i] = i + 1;//采用分治算法,构造整个赛程表for (int r = 1; r < n; r <<= 1) {for (int i = 0; i < n; i += 2 * r) { //i是呈现2*r增长//将左上角的r方块,移到右下角copy(a, r, r + i, 0, i, r);//将左下角的r方块,移到右上角copy(a, r, i, 0, r + i, r);}}return a;}private static void copy(int[][] a, int tox, int toy, int fromx, int fromy, int r) {for (int i = 0; i < r; i++) {for (int j = 0; j < r; j++) {a[tox + i][toy + j] = a[fromx + i][fromy + j];}}}public static void main(String[] args) {System.out.println("请输入参赛人数:");Scanner scan = new Scanner(System.in);Integer read = scan.nextInt();int num = read.intValue();if (num % 2 != 0) {System.out.println("输入人数不满足要求");System.exit(0);}int[][] a = table(num);for (int i = 0; i < a.length; i++) {for (int j = 0; j < a[0].length; j++) {System.out.print(a[i][j] + "|");}System.out.println();}}
}
分治法-循环赛日程表问题相关推荐
- 分治法-循环赛日程表
问题描述 循环赛日程表:有n = 2^k个运动员要进行网球循环赛 赛程表满足: 每个选手必须与其他n-1个选手各赛一次 每个选手一天只能参赛一次 循环赛在n-1天内结束 解题思路 将比赛日程表设计成一 ...
- 分治法——循环赛日程表
总共2^k个选手,正好为2的整数幂,每位选手每天只能比一次,必须与其他选手各比赛一次,总共n-1天.如图所示以天数为横坐标,以运动员编号为纵坐标,我们得到了一个比赛日程表. 不难发现,图中左上角的红框 ...
- 分治法循环赛c语言,循环赛问题分析和C语言代码-分治法.doc
WORD格式整理版 学习好帮手 问题描述:设有n个运动员要进行网球循环赛.设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次: (2)每个选手一天只能赛一次: (3)当n ...
- 算法-分治法-循环赛的日程安排
问题:设有n=2^k个选手参加循环赛,要求设计一个满足以下要求比赛日程表: 1)每个选手必须与其它n-1个选手各赛一次: 2)每个选手一天只能赛一次. 按照上面的要求,可以将比赛表设计成一个n行n-1 ...
- 用递归与分治策略求解网球循环赛日程表_算法设计:分治法(比赛日程安排)...
一.算法思路 1.思路 分治算法的思想是:对于一个规模位N的问题,若该问题可以容易解决(比如规模N较小),则直接解决,否则将其分解为M个规模较小的子问题,这些子问题互相独立,并且与原问题形式相同,递归 ...
- 算法复习第三章分治法
算法复习第三章分治法 循环日程表 最近点对 快速排序: 循环日程表 最近点对
- 分治法求循环赛日程表
设有n=2^k个运动员要进行网球循环赛.现要设计一个满足以下要求的比赛日程: (1)每个选手必须与其他n-1个选手各赛一次: (2)每个选手一天只能赛一次: (3)循环赛一共进行n-1天. 按要求可将 ...
- 分治法解决循环赛日程表
分治法解决循环赛日程表 问题描述 设有n=2^k个运动员要进行羽毛球循环赛,现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次. (2)每个选手一天只能比赛一次. ( ...
- 循环赛日程表算法——分治法
一.问题描述: 设有n=2^{k}个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表: (1)个选手必须与其他n-1个选手各赛一次: (2)每个选手一天只能赛一次. 按此要求,可将比赛日程表 ...
最新文章
- 13装饰器和内置函数
- pandas读写结构化数据(read_csv,read_table, read_excel, read_html, read_sql)
- 放心,GPT-3 不会“杀死”编程
- 将功能绑定到Twitter Bootstrap Modal关闭
- c语言编写心理测试,求各位大神赐教!我做了一个“心理测试的答题卷”编程,总共有1...
- 将span隐藏的函数_分类汇总函数Subtotal和Aggregate应用技巧解读
- Caffe Blob Dtype理解
- 别人7天乐,运维还苦逼值班?
- java.util.Locale简介
- ps3存档是php文件,PS3存档修改图文详细全教程
- django准备 —环境配置,及其虚拟环境安装、django安装、数据库安装、新建项目...
- 关于java通过反射 获取/修改 对象属性值的一些注意事项
- CSS 部分知识点 总结
- 第一个Java程序示例——Hello World!【转】
- new对象后的代码块(匿名类)
- 软件过程模型的管道理论
- 现金流量表模板2020_这位女会计编制现金流量表,一下子唰唰唰的整理好了
- html点击冒泡事件,JavaScript 浏览器事件机制(捕获、冒泡、委托)
- 试试看:把电脑时间调到2099年12月31号之后,会发生什么
- 硅树脂油漆申请美国标准UL 790 Class A 合适吗?
热门文章
- 65. 不用加减乘除做加法
- 一加9系列怎么样?性价比优选成为大众靠谱选择
- SELinux中的Apache和MySQL设定
- python 编译出现SyntaxError: Non-ASCII character ‘\xe8‘ in file in file serverinfo.py on line 4, but no
- js实现倒数日/纪念日功能:输入一个日期和重复类型,计算当天到该日期的天数
- 关于表格的增删改!!我必须泄个恨了!!
- 自己在网站搭建用到的一些网站
- 联想小新潮7000黑苹果教程_联想小新潮7000装win10系统教程
- sharemouse pro_出乎意料的高规格 华硕B460重炮手主板评测(全文)_华硕 TUF GAMING B460M-PRO_游戏硬件主板...
- 2020大连西山居暑期实习面经(已OC)