首页 > 其他分享 >比赛日程问题

比赛日程问题

时间:2024-01-20 17:35:29浏览次数:27  
标签:偶数 比赛 日程 -- 斜线 矩阵 问题 int 选手

问题描述:

1.设有n(n为任意值)个选手进行循环赛,手工设计一个满足以下要求的比赛日程表:

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

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

(3) 循环赛一共进行n-1天。

算法设计:

假设有N名选手参赛,不妨构造一个N×N的矩阵。在矩阵第一行填充1,2,…,N,第一列填充1,2,…,N。矩阵定义:把矩阵的第一列作为参赛选手的编号,第2~N列作为某一参赛选手的对手,显然任意的人数的选手其第一行都是一行选手,对手为2,3,…,N号选手,第一列是所有选手编号1,2,…,N。但是以上构造存在一个问题,就是这种假设默认了参赛选手人数是偶数,因为只有人数是偶数的情况下才只会需要N-1天(N-1列参赛选手)就完成比赛。所以我们不妨先考虑是选手是偶数的情况。

按照以上方法构造出来的答案如下(以N=6为例,取其它偶数情况亦同):

从以上结果寻找规律:

  1. 对角线上的元素全部为1。
  2. 考虑所有与对角线平行的斜线,对于上半矩阵,将对角线作为第一条斜线,之后的第2,3,…,N-1条斜线上的取值全部依次为2,3,…,N-1。如果斜线中的某一行原本的要取的值与所在行数相同,则取最大值N(如图1,第二行第三列位于第二条斜线,原本要取2,当因为他也在第二行,故取最大值6)。对于下半矩阵,规律也是类似的,将对角线作为第一条斜线,之后的第2,3,…,N-1条斜线取值依次为N-1,N-2,N-3……。同样的如果要取的值与行数相同则取最大值N。

根据以上规律,我们得到当N等于偶数时算法设计的思路:

  1. 按照上述规律对上半矩阵赋值。
  2. 对下半矩阵赋值。
  3. 对于得到矩阵,由于其每一列的和必定为sum=1+2+⋯+N,故用sum减去前N-1列的值,得到该列最后一行的值。

然后考虑N为奇数的情况(以N=7为例,其它奇数情况亦同),构造矩阵情况如下:

由构造的结果发现,对于奇数情况,我们可以先为他添加1使其变为偶数人的情况,不同的是,当斜线上存在相同值时我们不是添加最大值,而是添加0(0表示轮空)。得到的结果矩阵删去最后一行就是我们所需要的结果了。所以对于偶数情况,我们的代码要改的地方就是将传入的N+1,然后相同值由添加N改为添加0即可。此外,由于删去了最后一行,我们不需要再考虑偶数时最后一行得到的值不正确的情况了,故不需要再对每一列求和。

算法分析:

时间复杂度:O(N^2),因为有两个嵌套的for循环,每个循环的次数都是N。
空间复杂度:O(N^2),因为创建了一个N*N的二维数组。

程序设计:

  1 #include <iostream>
  2 
  3 using namespace std;
  4 
  5 int a[101][101] = {0};
  6 
  7 int main(int argc, const char * argv[]) {
  8 
  9 int N, i, j, k;
 10 
 11 cout << "请输入参赛人数:";
 12 
 13 cin >> N; // 比赛人数
 14 
 15 for (i = 1; i <= N; i ++){
 16 
 17 a[1][i] = a[i][1] = i;
 18 
 19 a[i][i] = 1;
 20 
 21 }
 22 
 23 bool flag = true; // N为偶数
 24 
 25 // 偶数人
 26 
 27 if(N % 2 == 0){
 28 
 29 // 上半区对角线方向赋值
 30 
 31 for (i = 2; i <= N; i ++){
 32 
 33 for (j = 1; j <= N-i; j ++){
 34 
 35 if (j + 1 == i) {// 如果要赋的值与所在行数相同
 36 
 37 a[i][i+j] = N;// 赋予最大值
 38 
 39 continue;
 40 
 41 }
 42 
 43 a[i][i+j] = j + 1;
 44 
 45 }
 46 
 47 }
 48 
 49 // 下半区对角线方向赋值
 50 
 51 for (i = 3; i <= N; i ++){
 52 
 53 for (j = i - 1, k = N - 1; j > 1; j --){
 54 
 55 if (k == i){
 56 
 57 a[i][j] = N;
 58 
 59 k --;
 60 
 61 continue;
 62 
 63 }
 64 
 65 a[i][j] = k --;
 66 
 67 }
 68 
 69 }
 70 
 71 int sum = 0, ss = 0;
 72 
 73 for(i = 1; i <= N; i ++){
 74 
 75 sum += i;
 76 
 77 }
 78 
 79 for (i = 2; i <= N; i ++) {
 80 
 81 for (j = 1; j <= N - 1; j ++){
 82 
 83 ss += a[j][i];
 84 
 85 }
 86 
 87 a[j][i] = sum - ss;
 88 
 89 ss = 0;
 90 
 91 }
 92 
 93 }
 94 
 95 // 奇数人
 96 
 97 else{
 98 
 99 flag = false;
100 
101 N += 1;
102 
103 for (i = 2; i <= N; i ++){
104 
105 for (j = 1; j <= N; j ++){
106 
107 if (j + 1 == i) {// 如果要赋的值与所在行数相同
108 
109 a[i][i+j] = 0;// 赋予0
110 
111 continue;
112 
113 }
114 
115 a[i][i+j] = j + 1;
116 
117 }
118 
119 }
120 
121 // 下半区对角线方向赋值
122 
123 for (i = 3; i <= N; i ++){
124 
125 for (j = i - 1, k = N - 1; j > 1; j --){
126 
127 if (k == i){
128 
129 a[i][j] = 0;
130 
131 k --;
132 
133 continue;
134 
135 }
136 
137 a[i][j] = k --;
138 
139 }
140 
141 }
142 
143 }
144 
145 
146 
147 if(flag){
148 
149 for (i = 1; i <= N; i ++) {
150 
151 for (j = 1; j <= N; j ++){
152 
153 cout << a[i][j] << "\t";
154 
155 if (j == 1){
156 
157 cout << "|\t";
158 
159 }
160 
161 }
162 
163 cout << endl;
164 
165 }
166 
167 }
168 
169 else{
170 
171 for (i = 1; i <= N - 1; i ++) {
172 
173 for (j = 1; j <= N; j ++){
174 
175 cout << a[i][j] << "\t";
176 
177 if (j == 1){
178 
179 cout << "|\t";
180 
181 }
182 
183 }
184 
185 cout << endl;
186 
187 }
188 
189 }
190 
191 return 0;
192 
193 }

结果输出:

标签:偶数,比赛,日程,--,斜线,矩阵,问题,int,选手
From: https://www.cnblogs.com/doris510/p/17976760

相关文章

  • 热血江湖服务端开服遇到的小问题详解
    热血江湖服务端开服遇到的小问题详解大家好我是艾西,今天跟大家分享下你们自己在搭建热血江湖或是开服过程中会遇到的小问题以及常用到的一些指令都是什么意思,有了一定的基础了解在后期您干起来肯定会更加的得心应手!出现ODBC链接不了:出现ODBC数据库配置连接失败的问题,可能是由于以下......
  • 记录一下 ArrayBlockingQueue 消息堆积的问题
    前言由于之前这个系统的日志记录是被领导要求写表的,在不影响系统性能的前提下,日志的入库操作肯定是要改成异步进行的,当时利用ArrayBlockingQueue+线程+AOP简单的去实现了一下,但是初版代码测试下来发现了一个很严重的问题,就是日志丢失的问题,本文由此而来。初步构思代码实现逻辑实......
  • VC 编译crt不同版本,Debug/Release混用问题
    extern"C" int__CRTDECL_imp__swprintf( _Pre_notnull__Post_z_wchar_t*const_Buffer, _In_size_tconst_BufferCount, _In_z__Printf_format_string_wchar_tconst*const_Format, ...){ int_Re......
  • SpringBoot项目通过注解快速解决,字典翻译,响应数据加密,数据脱敏等问题
    简介在几乎所有SpringBoot项目中都会面临字典翻译,接口数据加密,数据脱敏的问题。在每个接口中单独的解决会非常繁琐,因此接下来介绍一下怎么通过注解快速解决这些问题。实现步骤1.引入maven坐标<dependency><groupId>io.gitee.gltqe</groupId><artifactId>......
  • spring--是如何解决单例模式下循环依赖问题的
    Spring解决单例bean的循环依赖主要依赖于容器的三级缓存机制,以及bean的提前暴露。这里是它如何工作的:三级缓存:一级缓存(singletonObjects):存储已经经过完整生命周期处理的单例bean,包括初始化和依赖注入等。二级缓存(earlySingletonObjects):存储早期的单例对象的引用,这些......
  • 0-1背包问题 初理解
    第一次做这题确实没什么思路,看了卡哥的视频也是似懂非懂,现在整理一下。首先明确变量有哪些,物品种类,单个物品重量,单个物品价值,背包的最大容量容量;这些变量该如何融入递推公式中呢?先明确题目所求的是什么,在背包容纳范围下的价值最大。为了求容量空间为N的价值最大,可以推想容量空......
  • 简单课程安排问题
    问题描述:假定某大学有门课程需要使用同一个教室来上课。显然,我们不能在一个教室同时上两门或多门课程。因此,每门课使用教室的方式是独享的。假定这n门课程的集合为C={c1,c2,...,cn}。每门课使用教室的时间为{si,fi},i=1,2,...,n。这里si=开始时间,fi=结束时间。假设我们的目标是容纳......
  • 汉诺塔问题
    四阶汉诺塔求解图:汉诺塔问题代码实现以及当n=5,10,15,20增大时,算法所用时间长短变化情况图像绘制:1importtime2importmatplotlib.pyplotasplt34defhanoi(n,source,target,auxiliary):5ifn>0:6#将n-1个盘子从源柱子移动到辅助柱子7hanoi(n-1,......
  • openeuler2203升级openssh9.4p1解决漏洞问题
    openeuler2203升级openssh9.4p1解决漏洞问题 1,使用rpmbuild将tar包打成rpm包,不喜欢编译升级的,使用RPM升级就方便多了。想使用openssh的源码包编译安装的,参考这里:OpenSSH-9.4p1(linuxfromscratch.org) 2,准备编译环境[root@centos7-31~]#  yuminstallrpm-buildzlib......
  • Visual Studio + QT环境 界面中文乱码问题及解决
    情况:  头文件开头加入预编译语句#pragmaexecution_character_set("utf-8") 效果:  参考:VS2019+qt解决中文乱码问题  ......