分治与减治算法实验:题目6 淘汰赛冠军问题

news2024/11/26 0:39:58

目录

前言

实验内容

实验流程

实验分析

实验过程

流程演示

写出伪代码

实验代码

运行结果

改进算法

总结


前言

淘汰赛冠军问题是一个经典的算法设计与分析的问题,它要求我们在给定的n个参赛者中,通过一系列的比赛,找出最终的冠军。这个问题可以用分治策略来解决,即将n个参赛者分成两组,分别在每组内进行比赛,得到两个子组的冠军,然后再让这两个子组的冠军进行比赛,得到最终的冠军。这样的过程可以递归地进行,直到只剩下一个参赛者为止。

本实验的目的是掌握分治策略的基本思想和应用方法,以及如何分析分治算法的时间复杂度。我们将使用C语言实现淘汰赛冠军问题的分治算法,并对其进行测试和评估。我们还将探讨如何改进分治算法,使其能够同时找出第二名和第三名的参赛者。

实验内容

假设有n个选手进行竞技淘汰赛,最后决出冠军的选手,请设计竞技淘汰比赛的过程,输出结果,输出时要求有文字说明。请任选一种语言编写程序实现上述算法,并分析其算法复杂度。

实验流程

  1. 根据实验内容设计算法伪代码进行算法描述;
  2. 利用C++/C/Java等编程语言对算法伪代码进行工程化实现;
  3. 输入测试用例对算法进行验证;
  4. 列出算法时间复杂度模型并与计算机运行统计时间进行对比分析

实验分析

竞技淘汰赛是一种比赛方式,它的规则是:n个选手进行比赛,每次比赛淘汰一半,直到决出冠军。这种比赛方式的过程可以用分治法或减治法来实现。其中,减治法是一种更为简单的实现方式。具体实现方法如下:

  1. 将所有选手分成n/2组,每组两个选手进行比赛,被淘汰者不参加以后的比赛。
  2. 将剩余选手分成n/4组,每组两个选手进行比赛,被淘汰者不参加以后的比赛。
  3. 重复上述步骤,直到剩余最后两个选手,进行一次比赛即可选出最后的冠军。

实验过程

流程演示

  1. 将参赛者编号存入数组b中,编号从0到N-1。
  2. 重复以下步骤,直到只剩下三个参赛者:
    1. 将数组b中的参赛者分成两组,每组有N/2个参赛者。
    2. 对于每组,比较两个参赛者的得分,将得分高的参赛者作为胜者,将其编号存入数组b中。
    3. 如果有奇数个参赛者,则将最后一个参赛者直接存入数组b中。
    4. 找出第一名、第二名和第三名的参赛者。
    5. 将第二名和第三名的参赛者编号存入数组b的后半部分,即从b[N/2]到b[N-1]。
  3. 如果只剩下三个参赛者,则直接找出第一名、第二名和第三名的参赛者。

写出伪代码

将参赛者编号存入数组b中,编号从0到N-1。
重复以下步骤,直到只剩下三个参赛者:
    将数组b中的参赛者分成两组,每组有N/2个参赛者。
    对于每组,比较两个参赛者的得分,将得分高的参赛者作为胜者,将其编号存入数组b中。
    如果有奇数个参赛者,则将最后一个参赛者直接存入数组b中。
    找出第一名、第二名和第三名的参赛者。
    将第二名和第三名的参赛者编号存入数组b的后半部分,即从b[N/2]到b[N-1]。
如果只剩下三个参赛者,则直接找出第一名、第二名和第三名的参赛者。

实验代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    int n = 16; // 选手数量
    int i, j, k;
    int *a = (int *)malloc(sizeof(int) * n); // 动态分配数组空间

    srand((unsigned)time(NULL)); // 初始化随机数种子

    for (i = 0; i < n; i++)
        a[i] = i + 1; // 初始化选手编号

    while (n > 1)
    {
        for (i = 0; i < n / 2; i++)
        {
            j = rand() % n;
            k = rand() % (n - 1);
            if (k >= j)
                k++;
            printf("%d vs %d\n", a[j], a[k]);
            if (a[j] > a[k])
                a[j] = a[n - 1 - i];
            else
                a[k] = a[n - 1 - i];
        }
        n /= 2;
    }

    printf("Winner: %d\n", a[0]);

    free(a); // 释放数组空间

    return 0;
}

这个算法是一个递归算法。在每次递归时,它将所有参赛者分成两组,并找出每组中得分最高的两个参赛者。这些胜者被传递给下一轮比赛。如果有奇数个参赛者,则最后一个参赛者直接晋级下一轮比赛。这样,每轮比赛都会减少一半的参赛者,直到只剩下三个人为止。

运行结果

改进算法

代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 10

int main()
{
    int i, j, k;
    int a[N], b[N];
    int max1, max2, max3;

    srand((unsigned)time(NULL));
    for (i = 0; i < N; i++)
        a[i] = rand() % 100;

    for (i = 0; i < N; i++)
        printf("%d ", a[i]);
    printf("\n");

    for (i = 0; i < N; i++)
        b[i] = i;

    while (N > 3)
    {
        k = N / 2;
        for (i = 0; i < k; i++)
        {
            j = b[2 * i] > b[2 * i + 1] ? 2 * i : 2 * i + 1;
            b[i] = b[j];
            if (a[b[j]] > a[b[j ^ 1]])
                b[k + i] = b[j];
            else
                b[k + i] = b[j ^ 1];
        }
        if (N % 2 == 1)
            b[k] = b[N - 1];

        max1 = a[b[0]];
        max2 = a[b[k]];
        max3 = a[b[k + ((a[b[k]] == max1) ? k : 0)]];

        printf("第一名:%d\n", max1);
        printf("第二名:%d\n", max2);
        printf("第三名:%d\n", max3);

        for (i = k; i < N; i++)
            a[b[i - k]] = a[b[i]];
        N = k;
    }

    if (N == 3)
    {
        if (a[b[0]] > a[b[1]])
            j = (a[b[1]] > a[b[2]]) ? 1 : 2;
        else
            j = (a[b[0]] > a[b[2]]) ? 0 : 2;
    }
    else
        j = (a[b[0]] > a[b[1]]) ? 0 : 1;

    printf("第一名:%d\n", a[b[j]]);
    printf("第二名:%d\n", a[b[(j + 1) % 2]]);
    printf("第三名:%d\n", a[b[N - j - 1]]);
}

这个程序使用了一个数组来存储选手的成绩,然后使用竞技淘汰赛的方式进行比赛。在每一轮比赛中,选手两两进行比赛,输者被淘汰,胜者晋级下一轮。最后,决出前三名选手。


总结

淘汰赛冠军问题是指在一个有n个参赛者的淘汰赛中,如何用最少的比赛次数确定冠军。一个简单的方法是采用单循环赛制,即每个参赛者都和其他n-1个参赛者比赛一次,然后统计胜场数,最多胜场的参赛者就是冠军。这种方法的比赛次数是n(n-1)/2,当n很大时,这个数目会很庞大。因此,我们需要寻找一种更高效的方法。

一个更好的方法是采用单淘汰赛制,即每次从剩余的参赛者中随机选出两个进行比赛,胜者晋级,负者淘汰,直到只剩下一个参赛者为止,这个参赛者就是冠军。这种方法的比赛次数是n-1,显然比单循环赛制要少得多。但是,这种方法有一个缺点,就是不能保证最强的参赛者一定能够获得冠军,因为他可能在某一轮中遇到了第二强的参赛者而被淘汰。因此,我们需要寻找一种既能减少比赛次数又能保证最强者获胜的方法。

一个更优的方法是采用分治策略,即将n个参赛者分成两组,每组有n/2个参赛者(假设n是偶数),然后分别在两组内使用单淘汰赛制确定两个小组的冠军,再让两个小组的冠军进行比赛,确定最终的冠军。这种方法的比赛次数是T(n) = 2T(n/2) + 1,根据主定理,可以得到T(n) = n - 1。这和单淘汰赛制相同,但是这种方法有一个优点,就是可以保证最强的参赛者一定能够获得冠军,因为他只可能在最后一轮中遇到第二强的参赛者。

为了验证这个方法的正确性和效率,我用C语言编写了一个程序来模拟这个过程。程序中使用了一个数组来存储n个参赛者的实力值(假设实力值越大越强),并使用了一个递归函数来实现分治策略。程序运行时可以输入n的值,并输出每一轮的比赛结果和最终的冠军。我分别测试了n=8,16,32,64,128等不同的情况,并观察了程序的运行时间和空间占用。结果表明,程序能够正确地输出冠军,并且运行时间和空间占用都随着n的增加而增加,但是增加幅度不大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/480307.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nginx负载均衡+RabbitMq集群及镜像队列(2)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、nginx是什么&#xff1f;二、搭建步骤1.软件和环境2.安装nginx3.负载均衡配置nginx.conf4.应用程序配置 总结 前言 提示&#xff1a;这里可以添加本文要记…

Linux套接字编程-3

在之前的套接字编程内容中&#xff0c;我们讲述完了UDP和TCP的主要内容&#xff0c;但是对于TCP通信中具体的实现还存在一些问题没有解决&#xff0c;所以我们本篇博客将对进行分析和解决。 目录 1.引入 2.多进程 3.多线程 1.引入 在上一篇博客中&#xff0c;当我们使用T…

sed进阶之模式替换

shell脚本编程系列 &符号可以代表替换命令中的匹配模式&#xff0c;不管模式匹配到了什么样的文本&#xff0c;都可以使用&符号代表这些内容。这样就能处理匹配模式的任何单词了。 echo "The cat sleeps in his hat." | sed s/.at/"&"/g&…

告别低效繁琐的Prometheus告警管理,Nightingale助你快速响应故障!

Prometheus的告警规则、记录规则都是采用配置文件管理&#xff0c;适合奉行Infrastructure as Code的公司或团队内部使用。但如果要把监控能力开放给全公司&#xff0c;就要支持协同操作的 UI&#xff0c;让各个团队互不干扰的同时共享成果。 开源方案&#xff1a; Grafana 擅…

No.053<软考>《(高项)备考大全》【冲刺7】《软考之 119个工具 (5)》

《软考之 119个工具 &#xff08;5&#xff09;》 84.文档审查:85.信息收集技术:86.核对表分析:87.假设分析:88.图解技术:89.SWOT 分析:90.风险概率和影响评估:91.概率和影响矩阵(包含在风险管理计划中):92.风险数据质量评估:93.风险分类(包含在风险管理计划中):94.风险紧迫性评…

快速多关键字统计

实例需求&#xff1a;在每个章节中统计关键字&#xff08;“√”, “”, “〇”, “空缺”&#xff09;的个数&#xff0c;B列中的章节编号作为章节划分的标识&#xff0c;例如1.1.1 ~ 1.1.5为第1.1章节&#xff0c;对应工作表的12 ~ 16行&#xff0c;其中黄色列为需要统计的数…

【软考数据库】第五章 计算机网络

目录 5.1 网络功能和分类 5.2 OSI七层模型 5.3 TCP/IP协议 5.4 传输介质 5.5 通信方式和交换方式 5.6 IP地址 5.7 IPv6 5.8 网络规划和设计 5.9 其他考点补充 5.10 网络安全技术 5.11 网络安全协议 前言&#xff1a; 笔记来自《文老师软考数据库》教材精讲&#xff…

从张鑫旭的demo中,我学到了图像拉伸的原理

文章收录&#xff1a; 个人网址&#xff1a;http://linglan01.cn/Github仓库&#xff1a;https://github.com/CatsAndMice/blog/issues 产品经理又有新需求啦&#xff0c;其中有一个图片上传后用户拉伸图像宽高的功能&#xff0c;评估后因要卡上线时间来不及砍掉了。保不准下一…

Java 基础进阶篇(四)—— 抽象类与模板方法设计模式

文章目录 一、抽象类、抽象方法概述二、抽象类的特征三、模板方法设计模式3.1使用场景3.2 实现步骤3.3 写作文案例 补充&#xff1a;final 和 abstract 是什么关系? 一、抽象类、抽象方法概述 在 Java 中 abstract 是抽象的意思&#xff0c;可以修饰类、成员方法。 abstract …

【LeetCode股票买卖系列:122. 买卖股票的最佳时机 II | 贪心 | 暴力递归=>记忆化搜索=>动态规划】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

基于 GS232 搭建的 SoC_up 说明

1.1 GS232 开源版本简介 GS232 开源版本不包含 DSP、浮点部件等。 TLB 大小为 32 项。 指令和数据 Cache 为 4 路组相连,每路大小为 4KB,Cache 行大小为 32 bytes。 对外接口为 32 位 AXI 接口。 1.2 1,soc_up结构 SoC_up 如上图所示。开源 GS232 对外有一个 AXI 接口,连…

「Codeforces」771-div2 E. Colorful Operations

E. Colorful Operations https://codeforces.com/contest/1638/problem/E 题目描述 给你一个数组&#xff0c;默认初始元素为 0 &#xff0c;颜色为 1&#xff0c;有三种操作&#xff1a; Color l r c&#xff1a;将 [l, r] 区间内的颜色修改为 cAdd c x&#xff1a;将所有颜…

Human Pose as Compositional Tokens 阅读笔记

人体姿态作为合成 token —— CVPR2023 论文链接 代码链接 摘要&#xff1a; 人体姿态常由身体关节的坐标向量或其热图embedding表示。虽然数据易于处理&#xff0c;但由于身体关节间缺乏依赖建模&#xff0c;即使是不现实的姿态也被接受。本文提出了一种结构化表示&#xff1…

el-form-renderer 使用指南

目录 前言 起步 使用 update-form && getFormValue 表单项动态显示或隐藏(hidden) 表单数据联动(on) 输入/输出格式化(inputFormat/outputFormat) set-options el-form-renderer 实践案例 案例一 案例二 自定义组件接入指南 前言 el-form-renderer是基于e…

Starting Windows PowerShell (启动 Windows PowerShell)

Starting Windows PowerShell (启动 Windows PowerShell) Windows PowerShell is a scripting engine .DLL that’s embedded into multiple hosts. The most common hosts you’ll start are the interactive command-line powershell.exe and the Interactive Scripting Envi…

【Java笔试强训 26】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;跳台阶扩…

Redis`数据结构`与`对象`概述

文章目录 Redis数据结构与对象概述一、数据结构1、简单动态字符串&#xff08;SDS&#xff09;SDS结构体定义SDS结构示意图使用SDS的五个优点 2、双端链表&#xff08;list&#xff09;链表结构体定义list结构示意图 3、字典&#xff08;dict&#xff09;字典结构体定义dict结构…

想要成为 NLP 领域的大牛?从 ChatGPT 的 5 大自然语言模型开始了解吧(LM、Transformer、GPT、RLHF、LLM)——小白也能看得懂

目录 前言ChatGPT基础科普——知其一点所以然1. LM2. Transformer3. GPT4. RLHF5. LLM 参考资料其它资料下载 前言 如果想在自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;领域内脱颖而出&#xff0c;那么你一定不能错过 ChatGPT 的 5 大自然…

软件设计师笔记

软件设计师笔记 计算机组成与体系结构 数据的表示、计算机结构、Flynn分类法、CISC与RISC、流水线技术、存储系统、总线系统、可靠性、校验码 1. 数据的表示 &#xff08;一&#xff09;进制转换 R进制转十进制使用按权展开法&#xff1a; 十进制转R进制使用短除法 二进制…

Python——狂肝两万字带你学会【类与对象】

目录 01-初始对象 生活中的数据组织 程序中的数据组织​ 使用对象组织数据 总结01 02-类的成员方法 类的定义和使用 成员变量和成员方法 成员方法的定义语法 注意事项 成员方法——代码演示 总结02 03-类和对象 现实世界的事物和类 类和对象 使用类和对象描述…