算法-日程表

news/2024/12/22 19:08:51/

1 题目

设有n-2个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:
①每个选手必须与其他n-1个选手各赛一次;
②每个选手一天只能赛一次;
循环赛一共进行n-1天。
按此要求可将比赛日程表设计成有n行和n-1列的表。在表中第i行和第j列处填入第i个选手在第j天所遇到的选手。

2 思路

按分治策略,可以将所有选手对分为两半,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。递归地用这种一分为二的策略对选手进行分割,直到只剩下两个选手时,比赛日程表的制定就变得简单了。这时只要让这两个选手进行比赛就可以了。
如果是n=2*可以对称分割,则可以这样排:
在这里插入图片描述

3 分析

主要是代码太多循环了,有点难分析。

3.1 各个参数的含义:

  • n:n=2^k,有n个选手(保证了n为偶数)
  • k:划分表,一共会划分k次(每次划分都是把n*n的表化成四个(n/2)*(n/2)嘛,很好理解)

3.2 四个循环:

  1. 里面的两个for循环:交叉填m*m大小的日程表(运行一遍我的代码就知道了,每次交叉填完就输出日程表)
  2. 第二层循环:因为最开始肯定m=1,把第一行的交叉填到第二行,一共会有n/2次这样的交叉填,第二层循环参数 t 就是用来控制这个交叉填次数的。
  3. 最外层循环:第二行填完了,就是第一次递归完成了;接下来将第一二行填到第三四行,其实这就是递归的第二层了,递归一共会有 k 层,所以原代码是外层是 for 循环 k 控制,我习惯写成 while,感觉更好理解;

3.3 交叉填为啥是那样写的:

我们每次填的时候会发现,他的行其实就是i=m+1 ~ i<=2m(因为每次填mm大小,所以最下行=最上行+m-1)。
但是清注意列虽然也是m宽,这个代码 j 的初始大小永远都是m+1,而列实际上是随着前面的交叉填填完后要后移2*m的,因此代码就是如下所写了。

3.4 建议

看文字确实很难理解,运行一遍我的代码就会清楚很多。
希望能帮到大家。(外加,算法好难,哭)

4 代码

#include<iostream>
using namespace std;
int a[10][10];//日程表 void Table(int k) { //有2^k个选手 a为比赛日程表int n=1;for(int i=1; i<=k; i++) //计算选手人数(n=2^k)n=n*2;for(int i=1; i<=n; i++) //初始化比赛日程表:设置日程表第一行a[1][i]=i;int m=1;//每次填充时,起始填充位置while(k--) { //问题被划分k次n/=2; 		//n=交叉填的次数//k=3 填第二行:     需要填 原n/2次  交叉填 因此for循环是t<=n //k=2 填第三、四行: 只需要 原n/4次  交叉填//k=1 填五六七八行: 只需要 原n/8次  交叉填 for(int t=1; t<=n; t++) { //交叉填 for(int i=m+1; i<=2*m; i++) { //控制行for(int j=m+1; j<=2*m; j++) { //j和t 和m一起控制列  //每天交叉填完两个m*m大小的方格,列就要往后移动两个m a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2];//左下角等于右上角的值a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m];//右下角等于左上角的值}}
/*					 i-m  j+(t-1)*m*2-m  ...  i-m  j+(t-1)*m*2...                       ......                       ...
待填的部份:	i    j+(t-1)*m*2-m       i    j+(t-1)*m*2... i+m+1 
*/    
//输出日程表方便理解for(int i=1; i<=8; i++) {for(int j=1; j<=8; j++) {cout<<a[i][j]<<" ";}cout<<endl;}cout<<"---------------"<<endl;}m*=2;//下一轮交叉填的大小变为原来的两倍//1*1 -> 2*2 -> 4*4 }
}int main() {Table(3);//调用函数 //输出日程表 for(int i=1; i<=8; i++) {for(int j=1; j<=8; j++) {cout<<a[i][j]<<" ";}cout<<endl;}
}

http://www.ppmy.cn/news/389523.html

相关文章

FullCalendar(日程管理控件)

(以下是我学习FullCalendar控件时&#xff0c;网络上收集的一些资料) 第一部分&#xff08;官方资料&#xff09; jQuery.fullCalendar官方网址: http://arshaw.com/fullcalendar/ jquery.fullCalendar英文文档: http://arshaw.com/fullcalendar/docs/ jquery.fullCalendar下载…

ES节点磁盘水位线cluster.routing.allocation.disk.watermark

为了控制es节点磁盘写入大小&#xff0c;es设置了水位线这一参数&#xff0c;具体有两个&#xff1a; cluster.routing.allocation.disk.watermark.low (Dynamic) Controls the low watermark for disk usage. It defaults to 85%, meaning that Elasticsearch will not alloc…

专属EE的精美电子漫画

关注、星标公众号&#xff0c;精彩内容每日送达 来源&#xff1a;网络素材 ▲ 图1 硬盘表面的指纹 ▲ 图2 电路中的维修人员 ▲ 图3 电路中的拆卸工人 ▲ 图4 电路进行局部维修 ▲ 图5 电路环境下的钻探工 ▲ 图6 磁盘表面的施工人员 ▲ 图7 搬运电阻 ▲ 图8 这个电容与有问题 …

推荐一款功能强大的日程管理App

我推荐一款待办事项管理的App&#xff0c;我认为功能强大&#xff0c;用习惯了堪称提效神器。名字叫《安心记待办》&#xff0c;可以下载试试&#xff0c;非常棒 ​ 编辑切换为居中 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 「安心记待办」主要功…

安卓简易日程表实现

文章目录 一、前言二、运行截图与功能说明三、知识点与参考1.数据库的操作2.显示月日历3.给TextView添加点击事件 四、完整代码1.数据库有关的类MySQLiteOpenHelper2.activity_main.xml3.MainActivity4.用于删除和修改的Activity的布局activity_edit_schedule.xml5.EditSchedul…

日程表详细设计说明

一、 功能分解 1. 日程管理 1.1新建&#xff1a; 功能详解&#xff1a;新建日程安排。日程安排项目包括&#xff1a;描述、地点、开始日期、开始时间、结束日期、结束时间、是否闹铃、闹铃提前时间、是否重复、重复类型、备注。 1.2查看&#xff1a; 功能详解&#…

日程表(生活作息)

精神鸦片&#xff1a;网络游戏&#xff0c;扑克麻将&#xff0c;抖音快手&#xff0c;微博微信&#xff0c;电影电视&#xff0c;娱乐八卦等 生活作息&#xff1a;06:30起床&#xff0c;10:30熄灯 良好行为习惯&#xff1a; 少玩手机&#xff0c;多玩电脑。 少逛抖音&#xf…

汽车电子Autosar之以太网SOMEIP

前言 首先&#xff0c;请问大家几个小小问题&#xff0c;你清楚&#xff1a; 你知道什么是SOME/IP吗&#xff1f;你知道为什么会产生SOME/IP即相关背景吗&#xff1f;你知道SOME/IP与SOA又有着哪些千丝万缕的联系呢&#xff1f;SOME/IP在实践中到底应该如何使用呢&#xff1f…