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

分治与递归

实验一:分治与递归

【实验目的】

深入理解分治法的算法思想,应用分治法解决实际的算法问题。

【实验性质】

验证性实验(学时数:2H)

【实验内容与要求】

1、设有n=2k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:⑴每个选手必须与其他n-1个选手各赛一次;⑵每个选手一天只能赛一次;⑶循环赛一共进行n-1天。按此要求可将比赛日程表设计成有n行和n列的一个表。表中第一列是选手编号,表中第i行和第j列(j>1)处填入第i个选手在第j天所遇到的选手。例如8个选手的日程表安排如右图所示。

要求:请设计算法,并采用C或C++语言编写程序实现上述功能,调试运行并对算法的时间复杂度进行分析。

【算法思想及处理过程】

首先,通过输入参赛人数n,判断n是否合法(是否为2的幂次方),如果不合法则输出错误信息。

然后,输入第一个选手的编号k。

调用roundrob函数,传入参数k和n。roundrob函数的作用是生成对阵表。

首先,判断n是否为2,如果是,则直接生成对阵表。对阵表是一个二维数组a,每个元素表示某个选手与另一个选手的对阵情况。

如果n不是2,递归调用roundrob函数,将n除以2传入,并分成两个子问题,分别解决。

递归结束后,对阵表的前一半行和后一半行进行交换,生成完整的对阵表。

最后,遍历对阵表,并输出每个元素的值。

在主函数中,先判断n是否合法,如果合法则调用roundrob函数生成对阵表,并输出。

如果n不合法,则直接返回。

【程序代码】

#include <stdio.h>

#include<iostream>

using namespace std;

int a[100][100]{};

void roundrob(int k, int n)

{

  

    if (n == 2)

    {

        a[k][0] = k + 1;

        a[k][1] = k + 2;

        a[k + 1][0] = k + 2;

        a[k + 1][1] = k + 1;

    }

    else

    {

        roundrob(k,n / 2);

        roundrob(k + n / 2,n / 2);

    }

    for (int i = k; i < k + n / 2; i++)

    {

        for (int j = n / 2; j < n; j++)

        {

            a[i][j] = a[i + n / 2][j - n / 2];

        }

    }

    for (int i = k + n / 2; i < k + n; i++)

    {

        for (int j = n / 2; j < n; j++)

        {

            a[i][j] = a[i - n / 2][j - n / 2];

        }

    }

}

int determine(int n)

{

    if (n % 2 == 0)

    {

        if (n / 2 == 1) return 1;

        determine(n / 2);

    }

    else

    {

        cout << "输入人数不合法" << endl;

        return 0;

    }

}

int main()

{

    int n;

    int k;

    cout << "请输入参赛人数" << endl;

    cin >> n;

    if (determine(n) == 1)

    {

        cout << "请输入第一个选手编号" << endl;

        cin >> k;

        k = k - 1;

        roundrob(k, n);

        int i = 0, j = 0;

        for (i = 0; i < n; i++)

        {

            for (j = 0; j < n; j++)

            {

                cout << a[i][j] << " ";

            }

            cout << endl;

        }

    }

    if (determine(n) == 0)

    {

        return 0;

    }

}

【运行结果】

程序运行结果截图。

【算法分析】

代码的时间复杂度为O(n^2),其中n为参赛人数。代码中使用递归的方式生成了一个二维数组a,数组的大小为n×n。在生成数组a的过程中,有两个嵌套的循环,每个循环的次数都是n/2,因此循环次数总共为n/2 × n/2 = n^2/4,所以时间复杂度为O(n^2)。另外,代码中还有一个determine函数,该函数的时间复杂度为O(logn),因为每次递归都将n除以2,直到n为偶数。

相关文章:

  • Java并发编程之线程池源码解析与实现详解
  • 在Java、Java Web中放置图片、视频、音频、图像文件的方法
  • LVGL欢乐桌球游戏(LVGL+2D物理引擎学习案例)
  • SpringSecurity入门(一)
  • TOGAF架构介绍
  • 一文理解什么是k-近邻算法
  • 【网络安全的神秘世界】磁盘空间告急?如何解决“no space left on device”的困扰
  • day38 ● 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯
  • 生活使用英语口语柯桥外语学校成人英语学习
  • HBase中Master初始化错误~
  • STM32无法烧写程序的故障排除
  • Flink的简单学习五
  • 鸿蒙开发:【线程模型】
  • 测试bert_base不同并行方式下的推理性能
  • STM32--DMA
  • centos安装java运行环境jdk+tomcat
  • JavaScript设计模式与开发实践系列之策略模式
  • JDK9: 集成 Jshell 和 Maven 项目.
  • js正则,这点儿就够用了
  • k个最大的数及变种小结
  • linux安装openssl、swoole等扩展的具体步骤
  • OSS Web直传 (文件图片)
  • Vue2.x学习三:事件处理生命周期钩子
  • 关于List、List?、ListObject的区别
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 算法-图和图算法
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​学习一下,什么是预包装食品?​
  • ###C语言程序设计-----C语言学习(3)#
  • #13 yum、编译安装与sed命令的使用
  • #php的pecl工具#
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (C语言)共用体union的用法举例
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (十三)Flask之特殊装饰器详解
  • (学习日记)2024.01.09
  • (转载)利用webkit抓取动态网页和链接
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET Core Web APi类库如何内嵌运行?
  • .net 生成二级域名
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • /usr/bin/env: node: No such file or directory
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • [100天算法】-不同路径 III(day 73)
  • [AIGC] 使用Curl进行网络请求的常见用法
  • [Angular] 笔记 9:list/detail 页面以及@Output
  • [Cloud Networking] Layer3 (Continue)
  • [go 反射] 进阶
  • [Java][方法引用]构造方法的引用事例分析
  • [Linux] 系统管理
  • [MySQL]基础的增删改查
  • [MySQL光速入门]003 留点作业...
  • [NOIP 2003] 栈(三种方法:DP、数论、搜索)