循环赛日程表问题

循环赛日程表 循环赛日程表 分治法不仅可以用来设计算法,而且再其他方面也有广泛应用:利用分治法设计电路、构造数学证明等。 循环赛日程标问题,设有n=2k个选手要进行循环赛,设计一个满足以下要求的比赛日程表: 每个选手必须与其他n-1个选手各赛一次; 每个选手一天只能赛一次; 循环赛一共进行n-1天。 按此要求,可以将比赛日程表设计成n行n-1列的表格,i行j列表示第i个选手在第j天所遇到的选手。 基本思路:按分治策略,将所有的选手分为两组,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。递归地用对选手 阅读详情

最近在学习算法分析与设计这门课时,遇到了循环赛日程表问题。我感觉课本上的方法并不是很好(浪费空间而又不好理解),而网上流传的代码也基本和课本上类似,于是我决定用自己的方式来实现这个算法。

目录

问题描述

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

  1. 每个选手必须与其他n-1个选手各赛一次;
  2. 每个选手一天只能赛一次;
  3. 循环赛一共需要进行n-1天
    由于n=2^k,显然n为偶数。

算法思路

根据分治法的思想,递归地将问题一分为二,直到只剩下两个人比赛,最后在将这些问题合并起来,这样问题就变得十分简单。日程表的制定过程中存在一定的规律,即第i行第j列表示第i个选手在第j天所遇到的选手。这样算法就很容易实现了。

first-time

2^1个选手的比赛日程表

当问题规模为2^1时,此时问题最为简单,只需要将每个选手复制到对角线位置即可。

second-time

2^2个选手的比赛日程表

当问题规模为2^2时,将问题划分为2个规模为2^1的子问题,先解决子问题,然后在将问题规模为2^1的子问题看作一个整体,并复制到对角线位置,这时即可得到总问题的解。

third-time

2^3个选手的比赛日程表

与上面类似,先将问题划分为4个问题规模为2^1的子问题,分别解决后,再将这些子问题看作一个整体分别复制到对角线处,即可得到两个问题规模为2^2的子问题,最后再将规模变大了的子问题分别复制到对角线处,即可得到总问题的解。

……

算法实现

这里我只对代码的关键部分做简要的解释,即下面部分:

#define N 3
...
int sche = pow(2.0, N);      // divide the problem to pow(2, k) subproblems
...

for (int j = 0; j < N; j++)
    {
        // gets the size of the problem,
        // every loop the problem will triple
        bw = pow(2.0, j);
        for (int r = 0; r < bw; r++)
        {
            for (int c = 0; c < sche; c++)
            {
                // uses round to get the index of problem block
                bid = (c + bw) / bw;
                c_offset = pow(-1.0, bid + 1) * bw;
                r_offset = bw;
                arr[r + r_offset][c + c_offset] = arr[r][c];
            }
        }
    }

代码中使用了三层循环,最外层的循环控制问题的规模,即当j=0时,问题规模最小,即前面介绍的规模为2^1的问题;当j=1时,问题规模为2^2;当j=2时,问题规模为2^3……以此类推。这部分可以最能体现分治法的特点,将大问题划分为小问题。

第二层与第三层分别控制元素的行和列,这两层循环主要负责解决不同规模的问题,简单地说就是分别将不同规模的问题块复制到对角线的位置。

为了完成这个看似简单的过程,我们首先需要找一下规律(由于2^k必为偶数,所以n为奇数):

  • 子问题规模为2^1(j=0)时,

a[0][0]–>a[1][1]

a[0][1]–>a[1][0]

a[0][2]–>a[1][3]

a[0][3]–>a[1][2]

…

a[0][n-1]–>a[0+2^0][(n-1)+2^0]

a[0][n]–>a[0+2^0][n-2^0]

也就是说当元素的ID(ID=列号+1)为奇数时,移动到右下角(横纵坐标分别加2^0);当列ID为偶数时,移动到左下角(横坐标减2^0,纵坐标加2^0)。

  • 子问题规模为2^2(j=1)时,

a[0][0]–>a[2][2]

a[0][1]–>a[2][3]

a[0][2]–>a[2][0]

a[0][3]–>a[2][1]

…

a[0][n-3]–>a[0][(n-3)+2^1]

a[0][n-2]–>a[0][(n-2)+2^1]

a[0][n-1]–>a[0+2^1][(n-1)-2^1]

a[0][n]–>a[0+2^1][n-2^1]

现在规律就没有那么明显了,但是如果我们按照整块来找规律的话,那么规律就相对容易找一些。你可以这样划分块:即按照2x2的块来划分,每个块都对应一个ID,同样当ID为奇数时,移动到右下角(横纵坐标分别加2^1);当ID为偶数时,移动到左下角(横坐标减2^1,纵坐标加2^1)。

NOTE:其实问题规模为2^1时,块的大小为1x1。

  • 当子问题规模为2^3(j=2)时,

a[0][0]–>a[4][4]

…

a[0][2]–>a[4][6]

…

a[0][4]–>a[4][0]

…

a[0][7]–>a[4][3]

很显然,这里块的大小为4x4,移动的方法我这里也就不在赘述了。

综上所述,块的大小分别是2^0x2^0,2^1x2^1,2^2x2^x,…,2^nx2^n,每次都按照块来进行对角线复制,这时规律就显而易见了,所以r(行ID)的最大值就是块的宽度。但是还有一个比较棘手的问题——如何将数组中的每个元素与块的ID一一映射呢?我经过一番思考终于找到了规律:

BLOCK_ID = (COL_ID + BLOCK_WIDTH)/BLOCK_WIDTH

原代码中是这样写的:

  bid = (c + bw) / bw;

其实上面这个式子的灵感来源于我最近在学的CUDA编程中一个经典例子,在那里我学到了圆整(rounding)这个概念(实际上很早就接触过这个东西,只是当时并没有这个概念),圆整的方式有很多,常见的就有向上圆整(round up)和向下圆整(round down),如果你对圆整感兴趣,可以参考相关词条rounding。在我的这个式子中就用到了向上取整的方式,很容易理解,这里就不在赘述了。

到这里,所有的问题都解决了。

NOTE:细心的朋友可能会注意到,源码中是按行复制的。这与图中按列复制并不一致,但原理是一样的。

你可以在这里下载源码。

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

分治法——循环赛日程表 问题描述设有n=2k个运动员要进行羽毛球循环赛,现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其它n-1个选手各赛一次; (2)每个选手一天只能比赛一次; (3)循环赛一共需要进行n-1天。 由于n=2^k,显然n为偶数。 按分治策略,将所有的选手分为两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。递归地用对选手进行分割,直到只剩下2个选手时,比赛日 阅读详情

相关推荐

分治法-循环赛日程表问题

问题描述: 设有n=2^k个运动员,要进行网球循环赛。 每个选手必须与其他n-1个选手各赛一次。 每个选手一天只能赛一次。 循环赛一共进行n-1天。 算法策略: 1、将所有的选手分为两半,n个选手的比赛日程表可以通过为n/2个选手设计的比赛日程表来决定。 2、递归地用对选手进行分割,直到只剩下2个选手时,只要让这2个选手进行比赛就可以了。 (1)当k=1时,即人数为2人,此时表为 ...

HeinSven的博客 4620

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

分治的核心思想就是:递归(分解)+ 合并:递归分解:将原问题(大问题)分解成和原问题相似的子问题(小问题)。递归分解首先需要明确的就是递归函数的定义(一般和题目给出的函数类似)是什么,先不用管此时函数的内部是怎么实现的,明白函数的定义也就知道了我们需要给函数传递的参数是什么,而这个参数一般就是我们将原问题划分为子问题的依据。

mc_故事与你的博客 1万+

循环赛日程表问题(分治算法)

循环赛日程表问题(分治算法) 设有n=2kn=2^kn=2k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n−1n-1n−1个选手各赛一次; (2)每个选手一天只能参赛一次; (3)循环赛在n−1n-1n−1天内结束 按此要求将比赛日程表设计成有nnn行和n−1n-1n−1列的一个表。在表中的第iii行,第jjj列处填入第iii个选手在第jjj天所遇到的选手。 题图来自:https://blog.youkuaiyun.com/weixin_44469806/article/

lhn的博客 4195

分治法解决循环赛日程表

分治法解决循环赛日程表 问题描述 设有n=2^k个运动员要进行羽毛球循环赛,现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次。 (2)每个选手一天只能比赛一次。 (3)循环赛一共需要进行n-1天。 由于n=2^k,显然n为偶数。 分治法求解思路 按分治策略,将所有的选手分为两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。

linovce的博客 3247

5.4 最长非降子序列5.5 循环赛日程表问题

5.4 最长非降子序列 【问题描述】一个序列,共 N 个元素。现在要求从序列找到一个长度最长、且前面一项不大于它后面任何一项的子序列。只需算出这个序列的长度。N≤100000。 【分析】 用动态规划求解,则状态转移方程为:f(i)=max{f(j)}+1( 且 i>j)。时间复杂度为 O(),n 很大时会超时。超时的原因是大部分时间都耗在了寻找 max{f(j)}上面。 根据这一点,我们可以对算法进行改进。假设数组 C[]已经是符合条件的最长非降子序列,C[i]表示序列中第 i 小的元素,那么我们就..

zhengheda的博客 230

循环赛日程表,分治法(n=2K,n为任意数),多边形旋转法,C++

笔者用5中方法解决循环赛日程表问题。 一、n=2^k,采用递归,指针数组解决,左上角和左下角填充,剩下的copy。 二、n=2^k,采用递归,指针数组解决,左上角填充,剩下的copy。 三、n为任意数,采用递归,指针数组解决。 四,n为任意数,采用多边形轮转法。 五、n为任意数,是笔者对多边形轮转法的优化。

【算法-分治策略应用】循环赛日程表问题

一、分治策略基本思想 1、Divide 将原始问题划分或者归结为规模较小的子问题(多数情况下是划分成2个) 2、Conquer 递归或迭代求解每个子问题 3、Combine 将子问题的解综合得到原问题的解 注意: 1、子问题与原始问题性质完全一样 2、子问题之间可彼此独立地求解 3、递归停止时子问题可直接求解 比较典型的应用例子是“归并排序法”和“快速排序法”,详细可

m0_37714470的博客 2521

Jaspersoft Studio 6.20.0 免注册安装指南(附下载链接)

本文提供了Jaspersoft Studio 6.20.0社区版的免注册安装详细指南。文章介绍了绕过官网注册获取安装包的多种可靠途径,并逐步详解了从启动安装器到首次运行的全过程,帮助用户快速完成安装与基础配置,高效开启报表设计工作。

mars5的博客 1683

【分治法之循环赛日程表问题】

分治法就是把一个复杂的问题分解成两个或更多个相同或相似的子问题,再把子问题分成更小的子问题……,直到最后子问题可以简单地直接求解,原问题的解即为子问题解的合并。在计算机科学中,分治法是一种很重要的算法,是很多高效算法的基础。分治法所能解决的问题一般具有以下几个特征:(1)原问题的规模缩小到一定的程度就可以很容易地解决;(2)原问题可以分解为若干个规模较小的相同问题,即原问题具有最优子结构性质;(3)利用原问题分解出的子问题的解可以合并为原问题的解;

red2brick的博客 965

EEGNet 网络代码解析与实战复现指南

本文详细解析了EEGNet这一轻量级卷积神经网络的结构与设计思想,重点阐述了其利用深度可分离卷积高效处理脑电信号的原理。文章提供了基于PyTorch的完整代码复现指南,包括网络搭建、数据模拟、训练调试及关键参数解析,旨在帮助读者掌握EEGNet的代码复现技巧,并将其应用于脑机接口等实际场景。

honey的博客 532

ARM CoreSight架构

CoreSight架构是现代复杂SoC的“飞行数据记录仪”(黑匣子)和“精密诊断仪”的结合体。它彻底改变了嵌入式系统的调试方式,从传统的“盲人摸象”变成了拥有“上帝视角”,是ARM生态系统能够支撑起从微控制器到高性能服务器芯片如此广泛产品线的重要基石技术之一。

guigenyi的专栏 1420

python实现循环赛日程表问题的算法_循环赛日程表问题

最近在学习算法分析与设计这门课时,遇到了循环赛日程表问题。我感觉课本上的方法并不是很好(浪费空间而又不好理解),而网上流传的代码也基本和课本上类似,于是我决定用自己的方式来实现这个算法。目录问题描述设有n=2^k个运动员要进行羽毛球循环赛,现要设计一个满足以下要求的比赛日程表:每个选手必须与其他n-1个选手各赛一次;每个选手一天只能赛一次;循环赛一共需要进行n-1天由于n=2^k,显然n为偶数。算...

weixin_39534780的博客 2588

用COMSOL计算复合材料板频散曲线:从建模到绘图全流程

导波在板结构中传播时,不同频率成分的速度不同,即频散现象。理解频散曲线是识别导波模态、确定相速度与群速度的基础,也是无损检测和结构健康监测中信号解读的关键。对于碳纤维增强复合材料等各向异性板,频散关系更加复杂,传统解析方法难以求解,数值仿真成为主流手段。通过COMSOL结合周期性边界条件与特征频率扫描,可以高效计算出复合材料板的频散曲线,进而绘制相速度和群速度随频率变化的图谱,为实验模态识别、换能器激励频率选择提供依据。本文以一个2毫米单向碳纤维板为例,详细介绍几何建模、材料参数设置、网格收敛验证、参数扫描

weixin_31412781的博客 232

网球循环赛比赛日程表n为奇数问题

初衷 在教材上看到这个问题的时候,对于奇数的处理百思不得其解,然而网上的答案要么就是n=2k的情况,要么就是自己根本都没有理解,给你讲了一大堆,各种情况,很麻烦,甚至有些是错的误人子弟。所以写下这篇思路,分享给各位。其实这个问题的核心就是分治的治该怎么去构造的问题。 问题 设有N个运动员要进行网球循环赛,设计一个满足以下要求的比赛日程表 (1)每个选手必须与其他n-1个选手各赛一次 (2)每个选手...

weixin_34321977的博客 3997

声品质粗糙度matlab,声品质的应用分析方法

声品质的应用分析方法2016-04-05 09:18:57阅读次数:14198摘要:声品质分析在噪声的主观评价方面已经得到越来越多的应用。本文比较了声品质分析与传统计权声级的区别,并介绍了在声品质分析的实际应用中,针对稳态信号、非稳态信号的几种不同分析方法,以及各分析方法的要求和特点。关键词:声品质,响度,尖锐度,粗糙度,波动度1前言传统评价噪声的方法主要为计权声压级,用以反映声音的大小。但是人耳...

weixin_30767323的博客 2438

基于航天宏图PIE-SAR软件的高分三号(GF-3)SAR影像的预处理

软件官网 航天宏图—国内领先的卫星运营与应用服务提供商(官网) 一、数据导入 数据导入-GF-3-根据模式选择 参数文件导入解压后GF-3数据的XML文件 通道自动填充 设置输出目录 确定 等待,加载图像、自动构建金字塔 二、复数数据转换 强度/幅度特征是SAR影像最主要的特征之一,基于SAR强度/幅度影像可以提取地物目标信息,因此需要将SAR复数数据转换为SAR强度/幅度数据。导入输入影像,设置参数类型,输出目录、命名、类型; 漫长的等待 三、多视 为提...

weixin_52127098的博客 9002

java 循环赛问题_分治法实现循环赛日程表问题

问题:设有n=2^k个选手参加循环赛,要求设计一个满足以下要求:1)每个选手必须与其它n-1个选手各赛一次;2)每个选手一天只能赛一次。3)循环赛共进行 n -1 天。分析:按照上面的要求,可以将比赛表设计成一个n行n-1列的二维表,其中第 i 行第 j 列的元素表示和第 i 个选手在第 j 天比赛的选手号。日程表如下:图片.png一、规律:1,左上角元素手动赋值 a[1][1] = 1; a[1...

weixin_32943857的博客 1045

群晖如何安装软路由OpenWrt/iStoreOS作为旁路由(含网络设置、设置密码、还原出厂设置等linux命令ipk包)

openwrt的固件。

XiaoqiangClub的博客 7016

线性时间选择,最接近点问题,循环赛日程表

文章目录1.线性时间选择 1.线性时间选择 选择:元素查找,搜索 这里元素选择问题主要是指中位数的选择问题 直接排序,一个一个找,找第一小,第二小,第中位数K小 1到k,查找之和,一共(n+1)/2项 也可以事先排序,然后找到序列中(n+1)/2项 比如选合并排序,O(nlogn) 如果1<=k<=6,则原问题转化为:在第1组中寻找第k个最小元素; 如果7<=k<=10,则原问题转化为:在第2组中寻找第k-j个最小元素,其中,j为第1组元素的总个数; 支

m0_46640227的博客 558

Qt实现窗口自适应分辨率大小

如果希望窗口大小始终保持与屏幕分辨率一致,可以将上述代码放在窗口的resizeEvent()函数中。这样,每当窗口大小发生变化时,都会自动调用resizeEvent()函数,从而实现窗口大小的自适应调整。在Qt中,可以通过一些简单的方法实现窗口大小随分辨率变化而自适应调整。获取到当前屏幕的分辨率后,可以根据需要调整窗口的大小。无论在何种分辨率下运行应用程序,窗口都能够正确地自动调整大小,提供更好的用户体验。除了调整窗口大小,还可以考虑将窗口设置为最大化,以充分利用屏幕空间。步骤2:调整窗口大小。

FuJavascript的博客 3654

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

c语言网球循环赛,网球循环赛比赛日程表n为奇数问题

初衷在教材上看到这个问题的时候,对于奇数的处理百思不得其解,然而网上的答案要么就是n=2k的状况,要么就是本身根本都没有理解,给你讲了一大堆,各类状况,很麻烦,甚至有些是错的误人子弟。因此写下这篇思路,分享给各位。其实这个问题的核心就是分治的治该怎么去构造的问题。ios问题设有N个运动员要进行网球循环赛,设计一个知足如下要求的比赛日程表算法(1)每一个选手必须与其余n-1个选手各赛一次数组(2)每...

weixin_42297742的博客 1553

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

算法:循环赛日程表问题

算法:循环赛日程表问题

m0_55769611的博客 330

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: MySQL忘记root登录密码怎么办(windows)
下一篇: 中值滤波(C++实现)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值