当前位置: 首页 > news >正文

2.11 循环赛日程表


  • 博主简介:一个爱打游戏的计算机专业学生
  • 博主主页: @夏驰和徐策
  • 所属专栏:算法设计与分析

目录

书本内容:

我的理解:

更优化的算法:

总结

1.注意实现问题

2.当用C语言和C++实现循环赛日程表算法时,需要注意以下几点:


书本内容:

 

分治法不仅可以用来设计算法,在其他方面也有广泛应用,如用分治思想来设计电路、
构造数学证明等。现举例说明。
设有1-2*个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:
① 每个选手必须与其他 n-1 个选手各赛一次;
② 每个选手一天只能赛一次;
③ 循环赛一共进行 n-1 天;
按此要求可将比赛日程表设计成有n行和n-1 列的表。在表中第之行和第j列处填入第i个选手在第;天所遇到的选手。按分治策略,可以将所有选手对分为两半,n个选手的比赛日程表就可以通过为1/2个选手设计的比赛日程表来決定。递归地用这种一分为二的策略对选手进行分割,直到只剩下两个选手时,比赛日程表的制定就变得简单了。这时只要让这两个选手进行比赛就可以了。图 2-12 所列出的正方形表是8个选手的比赛日程表。其中,左上角与左下角的两小块分别为选手 1至选手4 和选手 5至选手8 前了天的比赛日程。据此将左上角小块中的所有数字按其相对位置抄到右下角,将左下角小块中的所有数字按其相对位置挱到右5上角,这样就分别安排好了选手 1至选手 4 和选手 5至选手8在后 4 天的比赛日程。依此思想,容易将这2个比赛日程表推广到具有任意多个选手的情形。在一般情况下,算法可描述如下:

 

void Table(int k,int **a)
{int n=1;for(int i=1;i<=k;i++){n*=2;}for(int i=1;i<=n;i++){a[1][i]=i;}int m=1;for(int s=1;s<=k;s++){n/=2;for(int i=m+1;i<=2*m;i++){for(int j=m+1;j<=2*m;j++){a[i][j+(t-1)*m*2]=a[i-m][j+t-1*m*2-m];a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2];}}}m*=2;}

我的理解:

循环赛日程表的构建可以用递归的分治算法来实现。具体地,将所有参赛队伍按照一定规则划分为两个子集,分别构建它们的日程表,最后将这两个日程表组合起来形成总的日程表。这个过程可以递归地进行,直到日程表中只剩下两个队伍时结束。

 

具体来说,可以采用如下的划分方式:将所有队伍分成两组,每组的大小相等或者相差不超过1。接下来,将第一组中的第i个队伍与第二组中的第i个队伍进行比赛,i从1到第一组队伍数目。这样就完成了一个轮次的比赛。然后,将第一组中的所有队伍沿着一个方向循环移动一位,将第二组中的所有队伍沿着相反的方向循环移动一位,得到新的一轮比赛。重复上述步骤直到完成n-1轮比赛,其中n为队伍的总数。这样就得到了完整的循环赛日程表。

在实现分治算法时,需要注意一些细节。例如,在划分队伍时,如果队伍的数目是奇数,需要将一个队伍暂时放到一边,等到下一轮再加入其中一个小组中。在组合两个子日程表时,需要注意将每个队伍在两个子日程表中的比赛分别放到总日程表中对应位置上。此外,还需要适当处理递归终止的情况。

循环赛日程表的构建是一个非常实用的算法问题,因为循环赛日程表在体育比赛、赛车比赛等领域有广泛的应用。采用分治算法可以降低算法的时间复杂度,提高算法的效率。

我的代码实现:

C语言实现:

#include <stdio.h>
#include <stdlib.h>void roundRobinSchedule(int n, int** schedule) {if (n == 1) {schedule[0][0] = 0;return;}int** subSchedule = (int**)malloc((n / 2) * sizeof(int*));for (int i = 0; i < n / 2; i++) {subSchedule[i] = (int*)malloc((n / 2 - 1) * sizeof(int));}roundRobinSchedule(n / 2, subSchedule);for (int i = 0; i < n / 2; i++) {for (int j = 0; j < n - 1; j++) {int team1 = subSchedule[i][j % (n / 2)] + (j / (n / 2)) * (n / 2);int team2 = (n - 1) - subSchedule[i][j % (n / 2)] + (j / (n / 2)) * (n / 2);schedule[team1][i] = team2;schedule[team2][i] = team1;}}if (n % 2 == 1) {for (int i = 0; i < n - 1; i++) {schedule[n - 1][i] = i;schedule[i][n - 1] = n - 1 - i;}}for (int i = 0; i < n / 2; i++) {free(subSchedule[i]);}free(subSchedule);
}int main() {int n = 6;int** schedule = (int**)malloc(n * sizeof(int*));for (int i = 0; i < n; i++) {schedule[i] = (int*)malloc((n - 1) * sizeof(int));}roundRobinSchedule(n, schedule);for (int i = 0; i < n; i++) {for (int j = 0; j < n - 1; j++) {printf("%d ", schedule[i][j]);}printf("\n");}for (int i = 0; i < n; i++) {free(schedule[i]);}free(schedule);return 0;
}

代码解释:

这段代码与之前的实现基本相同,只是使用了动态内存分配来创建二维数组。在 main 函数中,我们先使用 malloc 分配一个 n 行的指针数组 schedule,并在 roundRobinSchedule 函数中也使用 malloc 分配了一个 n/2 行、(n/2-1) 列的二维数组 subSchedule。在完成循环赛日程表的构建后,我们需要记得先释放 subSchedule 申请的内存,再释放 schedule 申请的内存,以避免内存泄漏。

C++实现:

#include <iostream>
#include <vector>using namespace std;vector<vector<int>> roundRobinSchedule(int n) {if (n == 1) {vector<vector<int>> result(1, vector<int>(1, 0));return result;}vector<vector<int>> schedule(n, vector<int>(n - 1));vector<vector<int>> subSchedule = roundRobinSchedule(n / 2);for (int i = 0; i < n / 2; i++) {for (int j = 0; j < n - 1; j++) {int team1 = subSchedule[i][j % (n / 2)] + (j / (n / 2)) * (n / 2);int team2 = (n - 1) - subSchedule[i][j % (n / 2)] + (j / (n / 2)) * (n / 2);schedule[team1][i] = team2;schedule[team2][i] = team1;}}if (n % 2 == 1) {for (int i = 0; i < n - 1; i++) {schedule[n - 1][i] = i;schedule[i][n - 1] = n - 1 - i;}}return schedule;
}int main() {int n = 6;vector<vector<int>> schedule = roundRobinSchedule(n);for (int i = 0; i < n; i++) {for (int j = 0; j < n - 1; j++) {cout << schedule[i][j] << " ";}cout << endl;}return 0;
}

代码解释:

这段代码实现了循环赛日程表的构建。其中,roundRobinSchedule 函数使用分治算法,递归地构建出小规模的日程表,并将它们合并起来得到最终的日程表。在实现过程中,我们使用了二维向量 schedule 来存储日程表,其第一维表示参赛队伍,第二维表示比赛轮次。在每个轮次中,我们使用 subSchedule 子日程表来记录参赛队伍之间的比赛对阵情况。最终,我们将子日程表中的比赛结果放到总日程表中对应的位置上,得到完整的循环赛日程表。

在 main 函数中,我们调用 roundRobinSchedule 函数构建了一个大小为6的循环赛日程表,并将其打印输出。

更优化的算法:

好的,下面我会具体讲解一下循环移位矩阵法和压缩算法。

循环移位矩阵法
循环移位矩阵法是一种将循环赛日程表问题转化为矩阵问题的方法,它可以通过矩阵的循环移位来生成日程表。

具体实现步骤如下:

(1)构造一个大小为n x n的矩阵,初始值都为0;

(2)在矩阵的第一行第一列放置1;

(3)依次填充矩阵的其它位置,填充规则如下:

a. 如果当前位置在矩阵的第一行,那么下一个位置应该是矩阵的最后一列的下一行。

b. 如果当前位置在矩阵的最后一列的下一行,那么下一个位置应该是矩阵的第一行。

c. 如果当前位置不满足a和b两个条件,那么下一个位置应该是当前位置的右上方。

(4)根据矩阵的每一行来生成对应的日程表。

该算法的时间复杂度为O(n^2),与传统的循环赛日程表算法相同,但是可以减少循环的次数,从而提高算法的效率。

压缩算法
压缩算法是一种只生成需要的那一行或那一列的算法,避免浪费时间和空间。该算法的实现思路是,首先利用循环赛日程表算法生成完整的日程表,然后只保留需要的那一行或那一列。

具体实现步骤如下:

(1)根据循环赛日程表算法生成完整的日程表;

(2)如果需要生成第i行日程表,则只保留日程表中第i行的数据,其它行的数据全部删除;

(3)如果需要生成第i列日程表,则只保留日程表中第i列的数据,其它列的数据全部删除。

该算法的时间复杂度取决于循环赛日程表算法的时间复杂度,如果原始算法的时间复杂度为O(n^2),则压缩算法的时间复杂度也为O(n^2)。但是压缩算法可以减少内存的占用,避免浪费时间和空间。

总结

1.注意实现问题

(1)在使用分治策略解決问题时 ,注意检查四个条件是否满足
(2)尽量保证划分出的子问题规模大致一致。平衡子问题思想
(3)如果可以使用递推的方式解决问题,尽量使用递推算法
(4)递归的分治算法的时间复杂性分析,要先写出其时间复杂
性的递归方程,然后用主定理或递归树解方程。
(5)用递归算法解决问题时,要分析出其边界条件和递归方程(过程) 

2.当用C语言和C++实现循环赛日程表算法时,需要注意以下几点:

  1. 在C语言中,需要手动进行内存管理,如使用malloc和free函数动态分配和释放内存,避免内存泄漏或访问非法内存。而在C++中,可以使用new和delete操作符,或使用智能指针等RAII技术来管理内存,使得代码更加安全和简洁。
  2. 在C语言中,数组下标从0开始,而在C++中,数组下标从1开始,因此在实现算法时需要注意数组的下标问题。
  3. 在C++中,可以使用STL容器如vector等来方便地管理数组,而在C语言中需要手动实现相关操作,如插入、删除和查找等。
  4. 在C++中,可以使用类和对象的概念来封装和组织代码,使得代码更加模块化和可复用。而在C语言中,可以使用函数和结构体等来实现类似的功能。
  5. 在实现算法时,需要考虑代码的可读性和可维护性,如合理命名变量和函数、添加注释、遵循编程规范等,从而使得代码更易于理解和修改。

3.这个算法和游戏的联系:

线性时间选择算法可以用来解决一些游戏中的问题。例如,有些游戏中需要计算排名,比如排行榜、竞技场排名等。在这些场景中,需要快速地找到某个玩家的排名,而线性时间选择算法可以用来解决这个问题。这怎么少得了王者农药呢?

 

具体来说,可以将玩家的战斗力作为数组的值,然后使用线性时间选择算法找到战斗力排名第k的玩家,这样就可以快速地计算出某个玩家在排名中的位置。

此外,线性时间选择算法还可以用来解决其他游戏中的问题,比如寻找最强的敌人、寻找最优的游戏策略等。

 

相关文章:

2.11 循环赛日程表

博主简介&#xff1a;一个爱打游戏的计算机专业学生博主主页&#xff1a; 夏驰和徐策所属专栏&#xff1a;算法设计与分析 目录 书本内容&#xff1a; 我的理解&#xff1a; 更优化的算法&#xff1a; 总结 1.注意实现问题 2.当用C语言和C实现循环赛日程表算法时&#xff…...

SpringBoot——SB整合mybatis案例(残缺版本)第三集

了解完使用阿里云存储的操作后&#xff0c;现在需要在案例里面集成阿里云进行开发。云服务——阿里云OSS的入门使用_北岭山脚鼠鼠的博客-CSDN博客 阿里云OSS——集成 对于前端传过来的图片要先上传到OSS&#xff0c;然后获取图片在云端的访问地址&#xff0c;存储到数据库里面…...

Baumer工业相机堡盟相机不满帧如何使用CameraExplorer设置相机参数让它的帧率达到满帧

项目场景 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机&#xff0c;可用于各种应用场景&#xff0c;如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能&#xff0c;可以实时传输高分辨率图像。此外&#xff0c;该相机还具…...

巴黎爱情回忆 NFT 作品集

由 Metaverse Studio 制作。 欢迎来到浪漫之都巴黎&#xff01;尽情游览美丽壮观的地标&#xff0c;探索法国文化。在离开之前&#xff0c;别忘了从《巴黎爱情回忆》NFT 作品集中带走一件纪念品。从世界著名的法国人物到标志性资产&#xff0c;这些 NFT肯定会为您的钱包带来巴黎…...

openai开放gpt3.5-turbo模型api,使用python即可写一个基于gpt的智能问答机器人

1安装python库 使用pip安装openai库&#xff0c;注意gpt3.5-turbo模型需要python>3.9的版本支持&#xff0c;本文演示的python版本是python3.10.10 pip install openai2创建api key 需要提前在openai官网上注册好账号&#xff0c;然后打开https://platform.openai.com/ac…...

GUI开发--LCD屏幕的使用(非第三方库)--笔记

导&#xff1a;界面交互需要GUI&#xff0c;GUI需要文字和图片&#xff0c;所有此处总结在M4芯片上实现GUI的基本操作&#xff01;该芯片具有160K大小的内存&#xff0c;有512K的flash&#xff1b;故而没有使用第三方库&#xff01; LCD屏幕的使用--笔记 1.汉字显示-两种方式…...

CesiumForUnreal实现地形等高线效果

文章目录 1.实现目标2.实现过程2.1 实现原理2.2 具体过程3.参考资料1.实现目标 在UE5中使用CesiumForUnreal插件添加Cesium World Terrain在线的世界地形,然后以25米为等高距,绘制一定范围内的等高线,如下图所示: 2.实现过程 由于这里直接使用CesiumForUnreal插件加载的在…...

Python爬虫——Python Selenium基本用法

Selenium 作为一款 Web 自动化测试框架&#xff0c;提供了诸多操作浏览器的方法&#xff0c;这里对其中的常用方法做详细介绍。 定位节点 Selenium 提供了 8 种定位单个节点的方法&#xff0c;如下所示&#xff1a; 定位节点方法方法说明find_element_by_id()通过 id 属性值定…...

仿真与测试:单元测试与Test Harness

本文描述单元测试的概念&#xff0c;以及Test Harness建立的方法和简单的单元测试过程。 文章目录1 单元测试1.1 场景举例1.2 简单的测试方法2 Test Harness建立2.1 模型配置2.2 创建Test Harness3 总结1 单元测试 单元测试&#xff0c;简单来说就是在Simulink模型中只测试一小…...

面试常问集锦——MySQL部分

Mysql速成大法 请签收MySQL灵魂十连 https://mp.weixin.qq.com/s?__bizMzI4NjI1OTI4Nw&mid2247488721&idx1&sneead82d2b7a0fdf993beacc4dfd60313&chksmebdef5e9dca97cff9d638877e5855850727ae26ebcfd60c7700ae53e311fa6ddb64b63bb9552&scene178&cur_a…...

算法训练第四十四天|完全背包理论 、518. 零钱兑换 II、377. 组合总和 Ⅳ

第九章 动态规划part06完全背包理论基础完全背包C测试代码总结518. 零钱兑换 II题目描述思路总结377. 组合总和 Ⅳ题目描述思路总结完全背包理论基础 参考&#xff1a;https://programmercarl.com/%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80%…...

0x06多层感知机

感知机 感知机形象的来看就是我们接触过的一个只有两个部分组成&#xff08;输出和输入&#xff09;组成的最简单的神经网络之一。 给定输入x&#xff0c;权重w和偏移b以及一个感知函数&#xff0c;感知机就能输出&#xff1a; 这个函数可以形象的用作二分类问题&#xff0c;…...

HTML是什么?HTML简介

HTML 英文全称是 Hyper Text Markup Language&#xff0c;中文译为“超文本标记语言”&#xff0c;专门用来设计和编辑网页。 使用 HTML 编写的文件称为“HTML 文档”&#xff0c;一般后缀为.html&#xff08;也可以使用.htm&#xff0c;不过比较少见&#xff09;。HTML 文档是…...

Linux定时服务

目录 1、定时器操作 2.cron表达式的语法规则 参考链接 1、定时器操作 sudo crontab -e 【选择2】 进入进行配置【需要按下 i 】 #sh /home/xx/crontabsh/test.sh的意思是&#xff0c;让sh解释器调用test.sh脚本&#xff0c;到达定时执行任务的效果 # 每一分钟执行一次 *…...

sgi_stl源码学习,官方文档3.2.3String package字符串封装,未完待续

https://www.boost.org/sgi/stl/character_traits.html char_traits<char> char_traits<wchar_t>traits翻译为特征、特性类&#xff0c;一般是指某种类型的特性类应该提供的一组接口、类型定义。 web页面描述了一些接口要求。感觉没有什么特别的。直接看代码吧 c…...

从JavaScript到Java(一):基础知识

Hello World Java和JavaScript虽然有不同的特点&#xff0c;但在一些概念和知识点上是相似的。本文从JavaScript开发者的角度出发&#xff0c;帮助你理解Java基础知识&#xff08;反过来也行&#xff09;。 // 解释型 console.log("Hello, World!");// 编译型 pub…...

Android编舞者类Choreographer小结

Android编舞者类Choreographer小结 作用 编舞者类的作用主要是控制绘制节奏&#xff0c;用于发起一次vsync垂直同步信号的监听&#xff0c;当垂直同步信号来的时候会回调注册的Runnable或者FramCallback Choreographer对象获取 Choreographer对象是通过它的getInstance方法…...

大专升本科难度大吗 需要考哪些科目

大专学历可以通过自考和成考提升学历到本科&#xff0c;自考的考试科目有12-16门左右&#xff0c;考试内容不难&#xff0c;但是考试周期长&#xff0c;需要考生通过所有课程才能申请毕业。成考专升本考试科目有政治&#xff0c;外语和专业课&#xff0c;考试内容简单&#xff…...

考研复试-英语问答+解答

每个问题2~3min 一、 1.考官问问题&#xff0c;没听明白 I’m sorry, I didn’t hear that clearly. May I ask you to repeat it, please? Sorry, I have no clear idea about this question for now, but I will think about it later. And if possible, I want to discuss …...

python 文件相关的操作 常用函数(读文件、写文件、文件的追加内容、修改文件内容、复制文件、按行读取文件、with open) json文件的读取

常用函数&#xff1a;open&#xff08;打开文件&#xff09;&#xff0c;read&#xff08;读文件到程序中&#xff09;&#xff0c;write&#xff08;写程序中的变量到文件&#xff09;&#xff0c;close&#xff08;关闭文件&#xff09; 示例1&#xff1a;读文件&#xff08…...

python 系列 06 -生成及解析二维码

0 说明 二维码不止一种&#xff0c;本文介绍最常见的QR二维码。由于不能发二维码截图&#xff0c;所以所有的执行结果都隐去了。完整版本可以移步到此查看&#xff1a;https://vblogs.cn/momo1938/article?id0407576070659864 1 安装包 python 可以使用qrcode来生成二维码&…...

2023第二届中国绿色钢铁国际峰会

会议背景 钢铁是当今世界上最常用的金属&#xff0c;普遍应用于世界各国基础设施建设与机械、汽车、飞机、船舶、家电等产品的生产制造中。但是&#xff0c;随着各国政府与行业净零排放目标的确立&#xff0c;钢铁行业的减排降碳也成为了关注焦点。据世界钢铁协会称&#xff0c…...

java 高考志愿填报系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 高考志愿填报系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0…...

机器学习 vs 深度学习:了解两者的异同

在人工智能领域中&#xff0c;机器学习和深度学习是两个重要的概念。尽管它们都可以用于处理复杂的数据和任务&#xff0c;但它们在其基本原理、算法和应用方面有着显著的不同之处。在本文中&#xff0c;我们将详细介绍机器学习和深度学习的定义、原理、算法和应用&#xff0c;…...

流行的 DAW编曲软件FL Studio 21 有什么新功能?

FL Studio 21 对流行的 DAW 和音乐制作软件进行了多项更新。最重要的变化包括&#xff1a;更快、更精确的音频包络和带有自动交叉推子的增益控制&#xff1b;一个能够标记、制作自定义颜色的标签和访问在线内容的新浏览器&#xff0c;以及一个带有可视化和擦除功能的内嵌音频播…...

【Java】抽象类和接口

抽象类和接口抽象类抽象类的概念抽象类语法抽象类的注意事项抽象类的作用接口接口的概念语法规则接口使用接口注意实现多个接口接口间的继承接口使用实例给对象数组排序Clonable 接口和深拷贝浅拷贝深拷贝抽象类和接口的区别抽象类 抽象类的概念 在面向对象的概念中&#xff…...

Lora:Low-Rank Adapation of Large Language models

Lora&#xff1a;Low-Rank Adapation of Large Language modelsIntroductionMethodExperiment代码Introduction 这篇论文最初与21.06上传与arXiv&#xff0c;作者指出在当时&#xff0c;NLP的一个重要范式是先训练一个通用领域的模型然后在通过微调适应不同的领域与数据&#…...

洛谷-P8466 [Aya Round 1 A] 幻想乡扑克游戏

题目&#xff1a;P8466 [Aya Round 1 A] 幻想乡扑克游戏 题目描述&#xff1a; 题目描述 斗地主是一种使用 &#xfffd;A 到 &#xfffd;K 加上大小王的共 5454 张扑克牌来进行的游戏&#xff0c;其中大小王各一张&#xff0c;其它数码牌各四张。在斗地主中&#xff0c;牌的…...

HBase性能优化方法总结

1. 表的设计 1.1 Pre-Creating Regions 默认情况下&#xff0c;在创建HBase表的时候会自动创建一个region分区&#xff0c;当导入数据的时候&#xff0c;所有的HBase客户端都向这一个region写数据&#xff0c;直到这个region足够大了才进行切分。一种可以加快批量写入速度的方…...

Linux基础内容(16)—— 文件系统

Linux基础内容&#xff08;15&#xff09;—— 缓冲区https://blog.csdn.net/m0_63488627/article/details/129824563?spm1001.2014.3001.5501 目录 1.基础知识 2.磁盘的存储原理 1.物理结构 2.存储结构 3.逻辑结构 1.基础知识 之前介绍的全是进程打开的文件是如何执行…...