循环比赛日常安排表

  • 题目描述
    • 提示
  • 题目解题
  • Code 递推
  • Code 递归
  • 结语

题目描述

设有n个选手进行循环比赛,其中n = 2^m,要求每名选手要与其他n - 1名选手都赛一次,每名选手每天比赛一次,循环赛共进行n - 1天,要求每天没有选手轮空。
输入
一行,包含一个正整数m。
输出
表格形式的比赛安排表(n行n列),每个选手的编号占三个字符宽度,右对齐。
样例输入 Copy
3
样例输出 Copy
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

提示

以表格的中心为拆分点,将表格分成A、B、C、D四个部分,就很容易看出有A=D,B=C,并且,这一规律同样适用于各个更小的部分。

题目链接 - 循环比赛日常安排表

题目解题

每名选手要与 n - 1 名选手比赛,那就需要比 n - 1 天,每天比赛的人不一样,并且打印出每日选手比赛的安排表

可以发现 1号选手 在 第1 天和2 号选手比赛,在 第3 天和4 号选手比赛
第7天(第n-1天) 和 6号选手比赛

同理:
2号选手 第1天和 1号选手比赛
4号选手 第3天和 1号选手比赛
8号选手 第7天和 1号选手比赛

题目最终目的是打印比赛日程表

  1. 我们发现了一个规律, 左上角和右下角 一模一样(红色表示)
    右上角和左下角一模一样(蓝色表示)

  2. 我们再看左上角的红色和右上角的蓝色,发现规律没?
    右上角的数值等于左上角的数组 + 4 (而且位置编号相差4)

  3. 现在我们仅仅看左上角的红色,里面的两个绿色和黄色基本一摸一样
    右上角的黄色数值等于左上角上的数值+ 2(而且位置编号相差 2)

  4. 可以发现右上角的数值等于左上角的值 加上 n(此时小方块的大小)
    左上角的绿色部分里的深蓝和紫色也满足以上规律

  5. 可以发现一个二维平面可以变为同等类型的小规模问题
    一个 8 * 8 可以变为一个 4 * 4
    一个4* 4 可以变为 一个 2 * 2
    一个2 * 2 可以变为 一个 1 * 1

这不就是分治思想嘛?哈哈哈,的确是的,大规模问题化为小规模问题
天下久和必分, 分久必和。

说明: 分治是一种算法思想, 随之大部分会用递归来实现,因为递归刚好体现啦分治。但是递归仅仅只是编程的一种实现,我们还可以用递推, 迭代等等)

分治仅仅是一种思想而不是实现编程的手段!!!

Code 递推

有了分治的思想,该题的递推很简单啦!从小到大 ,从1 往外推

#include <stdio.h>
int a[100][100];
void gen(int x, int y, int d)
{//gen函数的作用是左上角的数值复制到右上角int i, j;for (i = x; i < x + d; i++) {for (j = y; j < y + d; j++)a[i][j + d] = a[i][j] + d;}
}
void cpy(int x1, int y1, int d, int x2, int y2)
{//左上角复制到右下角, 右上角复制到左下角int i, j;for (i = 0; i < d; i++){for (j = 0; j < d; j++)a[x2 + i][y2 + j] = a[x1 + i][y1 + j];}
}
void print(int x, int y)
{int i, j;for (i = 0; i < x; i++){for (j = 0; j < y; j++)printf("%3d", a[i][j]);printf("\n");}}
int main()
{int d = 1;a[0][0] = 1;//首先左上角为1int m;scanf("%d", &m);for (int i = 1; i <= m; i++) {gen(0, 0, d);//右上角的值等于左上角的值 + 1cpy(0, d, d, d, 0);//左下角的值等于右上角cpy(0, 0, d, d, d);//右下角的值等于左上角d = d * 2;//d的值扩大2倍}//当i = 1的时候,进行第一次循环时1 2 2 1 //当i = 2 时,进行第二次循环d = 21 2 3 42 1 4 33 4 1 24 3 2 1//................................print(d, d);//最终打印return 0;
}

当然该题可以递推那么也是可以递归的,大部分的代码中递归和递推可以相互转换的。

Code 递归

理解该题的分治策略以及递推的实现,递归so easy! 不做过多的解释!

#include <stdio.h>
#include <math.h>
void fun(int d)
{if (d == 0) return ;//递归结束边界fun(d/2);//每次递归都 / 2//下面代码部分基本不变gen(0, 0, d/2);cpy(0, d/2, d/2, d/2, 0);cpy(0, 0, d/2, d/2, d/2);
}
void gen(int x, int y, int d)
{int i, j;for (i = x; i < x + d; i++) {for (j = y; j < y + d; j++)a[i][j + d] = a[i][j] + d;}
}
void cpy(int x1, int y1, int d, int x2, int y2)
{int i, j;for (i = 0; i < d; i++){for (j = 0; j < d; j++)a[x2 + i][y2 + j] = a[x1 + i][y1 + j];}
}
void print(int x, int y)
{int i, j;for (i = 0; i < x; i++){for (j = 0; j < y; j++)printf("%3d", a[i][j]);printf("\n");}
}int main()
{int d = 1;a[0][0] = 1;int m;scanf("%d", &m);int k = pow(2, m);fun(k);//其实就是用一个fun函数来自我调用print(k, k);return 0;
}

结语

当然新手上路,该题的分治策略讲解也许会有许多不足,多多谅解!

此处附上循环比赛日常安排表的视频链接, 推荐看一看来加深分治思想的理解和巩固 https://www.bilibili.com/video/BV1rp4y1X7mb

分治法 —— 循环比赛日程安排表相关推荐

  1. 分治法——循环赛事日程表

    问题描述: 设有n=2^k个运动员要进行网球循环赛.现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次:      (2)每个选手一天只能参赛一次:      (3) ...

  2. 算法复习第三章分治法

    算法复习第三章分治法 循环日程表 最近点对 快速排序: 循环日程表 最近点对

  3. 0008算法笔记——【分治法】循环赛事日程表

    问题描述: 设有n=2^k个运动员要进行网球循环赛.现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次:      (2)每个选手一天只能参赛一次:      (3) ...

  4. 分治法【锦标赛问题:设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次; (2)每个选手一天只能赛一次; (3)循环赛一共进行n-1天。】

    目   录 1.问题 2.问题分析 3.程序代码(非递归) 4.程序代码(递归) 5.总结 1.问题 锦标赛问题:设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次: ( ...

  5. 倒数58天 -- 分治法 -- 使用循环求方程的一个解

    #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cmath ...

  6. chatGPT教你算法(4)——分治法

    0. 引言 在计算机科学中,分治法是一种用于解决复杂问题的常用方法.它的核心思想是将大问题分解为若干个规模较小的子问题,递归地解决这些子问题,最后再将它们的结果组合起来得到原问题的解. 本博客将向大家 ...

  7. 用递归与分治策略求解网球循环赛日程表_算法设计:分治法(比赛日程安排)...

    一.算法思路 1.思路 分治算法的思想是:对于一个规模位N的问题,若该问题可以容易解决(比如规模N较小),则直接解决,否则将其分解为M个规模较小的子问题,这些子问题互相独立,并且与原问题形式相同,递归 ...

  8. 信息奥赛一本通(1325:【例7.4】 循环比赛日程表)

    1325:[例7.4] 循环比赛日程表 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 6257     通过数: 3483 [题目描述] 设有N个选手进行循环比赛 ...

  9. 卷王李富贵算法每日一题--分治算法(四)--循环比赛

    循环比赛 ## 问题: 有N个运动员进行单循环赛,即每个运动员要和所有其他运动员进行一次比赛.1.试用分治法为N个运动员安排比赛日程. 要求每个(或队)运动员每天只能进行一场比赛,且当运动员人数(队数 ...

  10. 【算法设计与分析】-- 分治法

    1.分治法的基本思想 分治法的基本思想是将一个规模为n的问题分解为k个规模为较小的子问题,这些子问题互相独立且与原问题相同,递归地求解这些子问题,然后利用子问题的解合并出原问题的解. 2.分治算法的设 ...

最新文章

  1. Unsupported format or combination of formats) Failed to parse onnx model
  2. chrome Native Client 让你可以使用 C 以及 C++ 语言开发 Web 应用
  3. frame buffer编程--画点功能和新增字符串代替RGBT
  4. 栈应用:判断字符串中括号是否成对出现
  5. 创建一个方便设计的自定义栅格布局
  6. c语言第一周项目,C语言第一周实战
  7. AXI 总线基本概念 - 如何理解outstanding传输
  8. App测试之性能测试流畅度fps测试
  9. linux操作系统期末试卷及答案,Linux操作系统期末复习题(含答案).pdf
  10. Liberal Arts:丧后即燃
  11. 数控g71编程实例带图_数控车床g71怎么编程?请举个例子谢谢了
  12. 那些不正经的前端笔试题
  13. ArcGIS Administartor localhost是无效主机名
  14. vmvare虚拟机无法读取ntfs的U盘解决方法,以及更换镜像下载源
  15. 鸿蒙基于linux系统,鸿蒙操作系统(HarmonyOS)是基于Linux的吗?尽管已知道它是基于微内核的...
  16. 佐治亚理工计算机科学在线硕士,佐治亚理工学院计算机研究生申请要求及截止时间一览...
  17. 正反斜杠的区别_正斜杠(/)和反斜杠(\)的区别
  18. ssi 指令 php,SSI使用详解(二)_PHP教程
  19. EasyRecovery15最新好用的电脑免费数据恢复软件
  20. unity基础知识----unity界面菜单翻译

热门文章

  1. CentOS7如何升级ruby版本
  2. 大学生必知到的外国典故
  3. centos pptp client 配置
  4. AlphaGo对战李世石谁能赢?两万字长文深挖围棋AI技术(一)
  5. 红米note5解锁教程_红米note手机密码忘了怎么解锁
  6. 【Java 8 新特性】Java Stream 通过min()和max()获取列表最小值和最大值
  7. 饥荒联机版加入服务器显示无应答,饥荒联机版水中木更新内容汇总 8月13日更新预览[多图]...
  8. Qt2D游戏开发引擎QtGameEngine使用入门10——游戏中如何响应用户输入(鼠标/键盘输入)
  9. 红帽linux9.0安装教程,红帽linux9.0安装教程
  10. 一般信道容量迭代算法c语言,(信息论编码)信道容量迭代算法