【算法设计与分析】实验——汽车加油问题, 删数问题(算法实现:代码,测试用例,结果分析,算法思路分析,总结)

news2025/6/8 8:21:51

说明:博主是大学生,有一门课是算法设计与分析,这是博主记录课程实验报告的内容,题目是老师给的,其他内容和代码均为原创,可以参考学习,转载和搬运需评论吱声并注明出处哦。

4-1算法实现题 汽车加油问题

问题描述:

一辆汽车加满油后可行驶 n 公里。旅途中有若干个加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。

编程任务:

对于给定的 n 和 k 个加油站位置,编程计算最少加油次数。

数据输入: 

由文件 input.txt 给出输入数据。第一行有 2 个正整数 n 和 k,表示汽车加满油后可行驶n 公里,且旅途中有 k 个加油站。接下来的 1 行中,有 k+1 个整数,表示第 k 个加油站与第k-1 个加油站之间的距离。第 0 个加油站表示出发地,汽车已加满油。第 k+1 个加油站表示目的地。

结果输出:

将编程计算出的最少加油次数输出到文件 output.txt。如果无法到达目的地,则输出”No Solution”。

输入文件示例

input.txt

7 7

1 2 3 4 5 1 6 6

输出文件示例

output.txt

4

请使用以下测试数据,并在报告中附上结果:

第一组

3708 6

33 20 83 77 26 59 67

第二组

630 37

46 43 94 77 45 98 11 60 15 42 7 69 61 54 51 65 50 16 28 60 91 17 44 54 93 52 32 54 41 80 88 54 55 27 58 59 92 73

第三组

181 46

54 94 61 51 51 57 73 96 32 45 97 73 44 88 25 14 53 59 79 41 63 100 25 57 35 55 61 88 54 40 77 1 53 86 67 59 13 56 96 56 75 45 37 76 99 41 94

实验代码

# n是总油量,k是距离列表
def calculation(n, k1, k):
    count = 0  # 加油次数
    current = n  # 当前油量
    for i in range(k1 + 1):
        if current >= k[i]:
            current -= k[i]
        else:
            count += 1
            current = n - k[i]
        if current < 0:
            return "No Solution"
    return count
with open("input.txt", 'r') as file:
    n, k1 = map(int, file.readline().split())
    k = list(map(int, file.readline().split()))
with open("output.txt", 'w') as file:
    file.write(str(calculation(n, k1,k)))

测试用例(示例)

测试用例1

测试用例2

测试用例3

实验结果分析

本次实验利用贪心算法正确实现沿途加油次数最少,可以通过两点证明该算法可以产生最优解,一点是本算法贪心性质的选择:每一步的局部最优选择能导致全局最优解(每次尽可能的使加油的次数最少,当前油量能到达下一站就不加油);一点是最优子结构:问题的最优解包含子问题的最优解(可以用数学归纳法进行证明)

主要算法思路

利用贪心算法,主要思路就是每次选择最好的情况,也就是尽可能使加油次数少,当当前油量可以跑完下一段路时选择不加油,不能跑完就选择加满。我用python实现,遍历所有,每到一个加油站都进行判断,最后返回次数即可。

时间复杂度分析

循环经行了K+1次,K是加油站的个数,内层循环是O(1)的基本操作,所以总时间复杂度为O(K)

实验小结

本次实验是很经典也是很基础的贪心算法的实际应用,在算法的思路方面我没有遇到问题。代码编写过程中,一个卡住的点是map(int, file.readline().split())

,我一开始写为map(file.readline().split() int)导致结果一直报错,这里提醒了我注意基本语法,函数参数的正确顺序传递问题。

4-2 算法实现题 删数问题

问题描述:

给定 n 位正整数 a,去掉其中任意 k≤n 个数字后,剩下的数字按原次序排列组成一个新的正整数。对于给定的 n 位正整数 a 和正整数 k,设计一个算法找出剩下数字组成的新数最小的删数方案。

编程任务:

对于给定的正整数 a,编程计算删去 k 个数字后得到的最小数。

数据输入:

由文件 input.txt 提供输入数据。文件的第 1 行是 1 个正整数 a。第 2 行是正整数 k。

结果输出:

程序运行结束时,将计算出的最小数输出到文件 output.txt 中。

输入文件示例

input.txt

178543

4

输出文件示例

output.txt

13

请使用以下测试数据,并在报告中附上结果:

第一组

651770271679223389093118623

13

第二组

2969814017117127739588196709348094559867047

19

第三组

8637848955234498476470337247531766424079

16

实验代码

def remove(a, k):
    stack = []  # 使用列表作为栈
    top = -1  # 栈顶指针初始化为-1(表示空栈)

    for digit in a:
        # 当还能删除数字,且栈不为空,且当前数字比栈顶数字小
        while k > 0 and top >= 0 and stack[top] > digit:
            stack.pop()  # 弹出栈顶元素
            top -= 1  # 栈顶指针减1
            k -= 1  # 剩余可删除次数减1

        # 将当前数字压入栈
        stack.append(digit)
        top += 1

    # 如果还有剩余删除次数(比如数字是升序的情况)
    if k > 0:
        stack = stack[:top + 1 - k]  # 从末尾删除剩余k个数字
        top = len(stack) - 1

    # 拼接结果并去除前导零
    result = ''.join(stack).lstrip('0')
    return result if result else '0'  # 如果结果为空字符串,返回"0"


with open('input.txt', 'r') as f:
    string = f.readline()
    a = []
    for i in string:
        a.append(i)
    k = int(f.readline())
with open('output.txt', 'w') as f:
    string_remove = remove(a, k)
    f.write(string_remove)

测试用例(示例)

测试用例1

测试用例2

测试用例3

实验结果分析:

本次实验成功实现了找出剩下数字组成的新数最小的删数方案,主要思路还是贪心算法,每次从前往后尽可能的删除较大的数。

算法思路:

我一开始的想法也是从前往后删除尽可能大的,为什么是从前往后删?因为前面的数更高位,对整个数的影响更大。而在具体实现方面,我选择用栈来辅助实现,从前往后依次把每个数字入栈。这里有一个卡住的点,我怎么“删除尽可能大的数”,是每当遇到一个比前面大的数就删除吗?这显然是最直观的想法。但是举一个很简单的例子,如果数是“4321”明显从4开始删除,但前面说的这种显然无法进行删除,所以最好的思路就是“遇到一个比前面小的数字,就删除前面的这个数字”,于是便能正确实现“删除尽可能大的数字”。

时间复杂度分析:

外层循环:遍历整个数字字符串,执行n次

内层while循环:每个数字最多被压入和弹出栈各一次 → 所有数字的操作总数是2n

所以总的时间复杂度为O(n)

实验小结:

这道题我有较多的实验心得想要记录,下面附上了我最开始写的不完善有错误的代码,回顾一下几个没考虑到位的点:

  1. 对于循环的条件:

很明显,我一开始想的是,当数字删除完了,循环就结束了,但是我没有考虑到,最终结果的存放,在Python中,字符串是不可以修改的数据类型,所以我必须用一个新的变量来表示,而最好的就是我用来删除的“栈”。这里就出现了问题,如果用栈来表示,那就必须遍历完所有数字,都要放入栈中,所以循环就应该是遍历整个字符串

  1. 对于特殊情况,当所有字符升序排列时,前面没有我们要找的“尽可能大的数字”,所以此时要从末尾删除,因为大的数字都在后面。
  2. 去除前导0:

当有0时,前面的数字不为0,便都是大于0的,所以前面的数字都要删除,此时0在最后会入栈,所以在转换为数字的时候要把前导的0删除。

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

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

相关文章

【C++进阶篇】C++11新特性(下篇)

C函数式编程黑魔法&#xff1a;Lambda与包装器实战全解析 一. lambda表达式1.1 仿函数使用1.2 lambda表达式的语法1.3 lambda表达式使用1.3.1 传值和传引用捕捉1.3.2 隐式捕捉1.3.3 混合捕捉 1.4 lambda表达式原理1.5 lambda优点及建议 二. 包装器2.1 function2.2 bind绑定 三.…

全生命周期的智慧城市管理

前言 全生命周期的智慧城市管理。未来&#xff0c;城市将在 实现从基础设施建设、日常运营到数据管理的 全生命周期统筹。这将避免过去智慧城市建设 中出现的“碎片化”问题&#xff0c;实现资源的高效配 置和项目的协调发展。城市管理者将运用先进 的信息技术&#xff0c;如物…

echarts柱状图实现动态展示时报错

echarts柱状图实现动态展示时报错 1、问题&#xff1a; 在使用Echarts柱状图时&#xff0c;当数据量过多&#xff0c;x轴展示不下的时候&#xff0c;可以使用dataZoom实现动态展示。如下图所示&#xff1a; 但是当鼠标放在图上面滚动滚轮时或拖动滚动条时会报错&#xff0c;…

408第一季 - 数据结构 - 线性表

只能用C/C&#xff01; 顺序表 闲聊 线性表的逻辑顺序和物理顺序相同 都是1234 顺序表的优点&#xff1a; 随机访问&#xff0c;随机访问的意思是访问的时间 和位置没有关系&#xff0c;访问下标1和100一样的&#xff0c;更深层就是直接计算 a100 * 数组大小&#xff0c;随便…

第23讲、Odoo18 邮件系统整体架构

目录 Odoo 邮件系统整体架构邮件发送方式邮件模板配置SMTP 邮件服务器配置邮件发送过程开发中常见邮件发送需求常见问题排查提示与最佳实践完整示例&#xff1a;审批通过自动发邮件门户表单自动邮件通知案例邮件队列与异步发送邮件添加附件邮件日志与调试多语言邮件模板邮件安…

HarmonyOS:Counter计数器组件

一、概述 计数器组件&#xff0c;提供相应的增加或者减少的计数操作。 说明 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 二、属性 除支持通用属性外&#xff0c;还支持以下属性。 enableInc enableInc(value: b…

sqlsugar WhereIF条件的大于等于和等于查出来的坑

一、如下图所示&#xff0c;当我用 .WhereIF(input.Plancontroltype > 0, u > u.Plancontroltype (DnjqPlancontroltype)input.Plancontroltype) 这里面用等于的时候&#xff0c;返回结果一条数据都没有。 上图中生成的SQL如下&#xff1a; SELECT id AS Id ,code AS …

Pandas 技术解析:从数据结构到应用场景的深度探索

序 我最早用Python做大数据项目时&#xff0c;接触最早的就是Pandas了。觉得对于IT技术人员而言&#xff0c;它是可以属于多场景的存在&#xff0c;因为它的本身就是数据驱动的技术生态中&#xff0c;对于软件工程师而言&#xff0c;它是快速构建数据处理管道的基石&#xff1…

数据库系统概论(十七)超详细讲解数据库规范化与五大范式(从函数依赖到多值依赖,再到五大范式,附带例题,表格,知识图谱对比带你一步步掌握)

数据库系统概论&#xff08;十七&#xff09;超详细讲解数据库规范化与五大范式&#xff08;从函数依赖到多值依赖&#xff0c;再到五大范式&#xff0c;附带例题&#xff0c;表格&#xff0c;知识图谱对比带你一步步掌握&#xff09; 前言一、为什么需要规范化1. 我们先想一个…

并发编程实战(生产者消费者模型)

在并发编程中使用生产者和消费者模式能够解决绝大多数的并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序整体处理数据的速度。 生产者和消费者模式&#xff1a; 在线程的世界中生产者就是产生数据的线程&#xff0c;而消费者则是消费数据的线程。在多线程开…

git小乌龟不显示图标状态解决方案

第一步 在开始菜单的搜索处&#xff0c;输入regedit命令&#xff0c;打开注册表。 第二步 在注册表编辑器中&#xff0c;找到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers 这一项。 第三步 让Tortoise相关的项目排在前…

获取 OpenAI API Key

你可以按照以下步骤来获取 openai.api_key&#xff0c;用于调用 OpenAI 的 GPT-4、DALLE、Whisper 等 API 服务&#xff1a; &#x1f9ed; 获取 OpenAI API Key 的步骤&#xff1a; ✅ 1. 注册或登录 OpenAI 账号 打开 https://platform.openai.com/ 使用你的邮箱或 Google/…

【Android基础回顾】五:AMS(Activity Manager Service)

Android 的 AMS&#xff08;Activity Manager Service&#xff09;是 Android 系统中的核心服务之一&#xff0c;负责管理整个应用生命周期、任务栈、进程和四大组件&#xff08;Activity、Service、BroadcastReceiver、ContentProvider&#xff09;的运行。它运行在系统进程 s…

pycharm中提示C++ compiler not found -- please install a compiler

1.最近用pycharm编译一个开源库,编译的依赖c compiler 2.单单使用pycharm编译&#xff0c;编译器报错C compiler not found – please install a compiler 3.需要在配置环境中引入对应库 4.从新编译后没有提示:C compiler not found – please install a compiler错误。

一站式直播工具:助力内容创作者高效开启直播新时代

近年来&#xff0c;随着互联网技术的不断进步和短视频、直播行业的爆发式增长&#xff0c;越来越多的企业和个人投入到直播电商、互动娱乐、在线教育等场景。直播运营过程中&#xff0c;涉及到数据统计、弹幕互动、流程自动化、内容同步等诸多环节。如何提升运营效率、减少人工…

以智能管理为基础,楼宇自控打造建筑碳中和新路径

在全球气候变化的严峻形势下&#xff0c;“碳中和”已成为各国发展的重要战略目标。建筑行业作为能源消耗与碳排放的“大户”&#xff0c;其运行阶段的能耗占全社会总能耗近40%&#xff0c;碳排放占比与之相当&#xff0c;实现建筑碳中和迫在眉睫。传统建筑管理模式下&#xff…

day029-Shell自动化编程-计算与while循环

文章目录 1. read 交互式初始化变量1.1 案例-安装不同的软件1.2 案例-比较大小 2. 计算2.1 bc2.2 awk2.3 expr2.4 let2.5 案例-计算内存的空闲率2.6 案例-检查域名过期时间和https整数过期时间 3. 循环3.1 循环控制语句3.2 for循环-c语言格式3.3 while循环3.3.1 案例-猜数字3.3…

Linux命令基础(2)

su和exit命令 可以通过su命令切换到root账户 语法&#xff1a;su [-] 用户名 -符号是可选的&#xff0c;表示是否在切换用户后加载环境变量&#xff0c;建议带上 参数&#xff1a;用户名&#xff0c;表示要切换的用户&#xff0c;用户名可以省略&#xff0c;省略表示切换到ro…

vue3 + vite实现动态路由,并进行vuex持久化设计

在后台管理系统中&#xff0c;如何根据后端返回的接口&#xff0c;来动态的设计路由呢&#xff0c;今天一片文章带你们解 1、在vuex中设置一个方法 拿到完整的路由数据 const state {routerList: []}; const mutations { dynameicMenu(state, payload) {// 第一步 通过glob…

学习路之php--性能优化

一、php周边优化 二、代码级优化 变量管理‌ 及时unset()释放大数组/对象&#xff0c;减少内存占用局部变量访问速度比全局变量快约2倍&#xff0c;优先使用局部变量大数组采用引用传递&#xff08;&$var&#xff09;避免内存 循环优化‌ 预计算循环次数&#xff1a; …