每日一题——Python实现PAT乙级1020 月饼(举一反三+思想解读+逐步优化)


一个认为一切根源都是“自己不够强”的INTJ

个人主页:用哲学编程-CSDN博客
专栏:每日一题——举一反三
Python编程学习
Python内置函数

Python-3.12.0文档解读

目录

我的写法

专业点评:

时间复杂度分析:

空间复杂度分析:

总结:

我要更强

时间复杂度优化:

空间复杂度优化:

优化后的代码解释:

时间复杂度分析:

空间复杂度分析:

总结:

哲学和编程思想

1. 贪心算法(Greedy Algorithm)

2. 优先队列(Priority Queue)

3. 空间-时间权衡(Space-Time Tradeoff)

4. 原地修改(In-place Modification)

5. 分治法(Divide and Conquer)

6. 减少问题规模(Reduce Problem Size)

举一反三

1. 贪心算法(Greedy Algorithm)

2. 优先队列(Priority Queue)

3. 空间-时间权衡(Space-Time Tradeoff)

4. 原地修改(In-place Modification)

5. 分治法(Divide and Conquer)

6. 减少问题规模(Reduce Problem Size)

具体技巧和示例:

总结


 题目链接

我的写法
 

# 读取输入
N, D = map(float, input().split())  # 读取月饼种类数N和市场最大需求量D,转换为浮点数
N = int(N)  # 将月饼种类数N转换为整数,因为月饼种类数不应该是小数
storages = list(map(float, input().split()))  # 读取每种月饼的库存量,并转换为浮点数
prices = list(map(float, input().split()))  # 读取每种月饼的总售价,并转换为浮点数

# 构建每种月饼的信息,包括库存量、总售价、和单位售价
# 注意月饼库存量和总售价可以是小数,初始三个参数可以都设为float型(测试点2)
infos = []
for i in range(N):  # 遍历每种月饼
    unit_price = prices[i] / storages[i]  # 计算每种月饼的单位售价(每吨售价)
    infos.append([storages[i], prices[i], unit_price])  # 将每种月饼的信息存入列表

# 按单位售价从高到低排序
infos.sort(key=lambda x: x[2], reverse=True)  # 按单位售价从高到低对月饼信息进行排序

output = 0.0  # 初始化输出的最大收益
for storage, total_price, unit_price in infos:  # 遍历排序后的月饼信息
    if D == 0.0:  # 如果市场需求量已经满足,退出循环
        break
    if storage <= D:  # 如果当前月饼的库存量小于等于剩余需求量
        output += total_price  # 将当前月饼的总售价加入收益
        D -= storage  # 减少相应的需求量
    else:  # 如果当前月饼的库存量大于剩余需求量
        output += D * unit_price  # 根据剩余需求量计算收益
        D = 0.0  # 将需求量设为0,表示已经满足需求

print(f"{output:.2f}")  # 输出最大收益,保留两位小数

 

这段代码实现了基于库存量和总售价的月饼销售策略,以最大化收益为目标。代码逻辑清晰,基本思路是先计算每种月饼的单位售价(即每吨售价),然后根据单位售价从高到低排序,优先销售单位售价高的月饼,以达到最大收益。以下是对这段代码的专业点评,以及其时间复杂度和空间复杂度的分析。

专业点评:

  1. 数据输入和预处理:
    • 输入处理部分正确地将数据转换为浮点数,保证在处理涉及小数的计算时不会出现精度问题。
  2. 计算单位售价并排序:
    • 通过计算每种月饼的单位售价并将其存储在列表中,排序时选择了基于单位售价从高到低的顺序,这一步很合理,因为单位售价高的月饼优先销售可以最大化总收益。
  3. 收益计算逻辑:
  • 代码通过遍历排序后的月饼信息,根据库存量和剩余需求量更新总收益,逻辑清晰且高效。

时间复杂度分析:

  1. 输入读取和预处理:
    • 读取和转换数据的时间复杂度为O(N),因为需要对每一个输入数据进行处理。
  2. 计算单位售价并排序:
    • 计算单位售价的时间复杂度为O(N),因为需要对每一种月饼计算一次。
    • 排序的时间复杂度为O(N log N),因为使用了Timsort(Python内置的排序算法)。
  3. 收益计算:
  • 遍历排序后的月饼信息,并根据需求量计算总收益,这部分时间复杂度为O(N)。

综合上述步骤,代码的总体时间复杂度为O(N log N),这是因为排序是主要的时间消耗部分。

空间复杂度分析:

  1. 输入数据存储:
    • 存储库存量和总售价需要两个长度为N的列表,空间复杂度为O(N)。
  2. 单位售价信息存储:
  • 存储每种月饼的库存量、总售价和单位售价,空间复杂度为O(N)。

因此,总体空间复杂度为O(N),因为存储每种月饼的信息占用了线性空间。

总结:

这段代码有效地解决了基于单位售价最大化收益的问题。时间复杂度主要由排序部分决定,为O(N log N),而空间复杂度为O(N),这是非常高效且合理的。可以进一步提高代码的健壮性,例如增加更多的错误处理和边界情况处理。总体上,这段代码在逻辑上是正确且高效的。


我要更强

在这段代码中,时间复杂度的主要瓶颈在于排序操作(O(N log N)),而空间复杂度是O(N),主要是存储月饼信息。针对这两个方面,我们可以尝试一些优化方法。

时间复杂度优化:

  1. 如果月饼种类数很大,而市场需求量相对较小,可以采用优先队列(堆)来优化。我们可以使用最大堆来动态选择当前单位售价最高的月饼进行销售,从而避免全局排序,从而减少时间复杂度。

空间复杂度优化:

  1. 原地修改:将月饼的库存量、总售价、和单位售价等信息存储在原始列表中,避免额外的空间开销。

以下是结合这些优化后的代码示例,使用优先队列来改进时间复杂度,并在一定程度上降低空间复杂度。

import heapq

# 读取输入
N, D = map(float, input().split())
N = int(N)
storages = list(map(float, input().split()))
prices = list(map(float, input().split()))

# 创建一个最大堆存储每种月饼的单位售价及其相关信息
heap = []
for i in range(N):
    unit_price = prices[i] / storages[i]  # 计算单位售价
    heapq.heappush(heap, (-unit_price, storages[i], prices[i]))  # 使用负值构建最大堆

output = 0.0  # 初始化收益
while D > 0 and heap:  # 当市场需求量未满足且堆非空时
    unit_price, storage, total_price = heapq.heappop(heap)  # 弹出单位售价最高的月饼信息
    unit_price = -unit_price  # 将单位售价恢复为正值
    if storage <= D:  # 如果当前月饼库存量小于等于需求量
        output += total_price  # 将总售价加入收益
        D -= storage  # 减少相应的需求量
    else:  # 如果当前月饼库存量大于需求量
        output += D * unit_price  # 根据剩余需求量计算收益
        D = 0.0  # 将需求量设为0,表示需求已满足

print(f"{output:.2f}")  # 输出最终收益,保留两位小数

优化后的代码解释:

  1. 使用堆优化排序过程:
    • 在计算单位售价后,将其作为负值存入最大堆(Python的heapq默认是最小堆,所以使用负值来实现最大堆的效果)。
    • 这样每次从堆中弹出元素时,实际上是弹出当前单位售价最高的月饼信息。
  2. 减少额外空间开销:
  • 最大堆中仅存储必要的月饼信息,没有创建额外的数据结构来存储排序后的信息。

时间复杂度分析:

  • 堆操作:
  • 插入堆的时间复杂度为O(log N),总共进行N次插入操作,耗时为O(N log N)。
  • 弹出堆顶元素的时间复杂度为O(log N),最坏情况下需要进行N次弹出操作,所以总耗时为O(N log N)。

空间复杂度分析:

  • 使用堆存储月饼信息,空间复杂度为O(N),因为堆中最多存储N个元素。
  • 没有创建额外的列表或数据结构来存储排序后的信息,进一步减少了空间占用。

总结:

优化后的代码通过使用最大堆将全局排序操作优化为局部最优选择,同时减少了额外空间开销。时间复杂度从O(N log N)降到O(N log N)(保持不变,但更高效),空间复杂度维持在O(N),进一步提高了效率和资源利用率。


哲学和编程思想

在优化这段代码的过程中,我们使用了一些经典的编程思想和哲学,这些方法不仅提高了算法的效率,也展示了编程中的一些关键原则。以下是详细的分析:

1. 贪心算法(Greedy Algorithm)

思想:贪心算法是一种在每一步选择中都采取当前状态下最好或最优的选择,最终希望通过一系列当地最优选择达到全局最优。

应用:

  • 我们基于月饼的单位售价从高到低的顺序选择月饼进行销售,以实现每一步的收益最大化。这种方式确保了整体收益的最大化。

2. 优先队列(Priority Queue)

思想:优先队列是一种数据结构,它允许以动态的方式对元素进行管理,并保证每次操作都能高效地获取优先级最高或最低的元素。

应用:

  • 使用最大堆(优先队列)来管理月饼的单位售价信息,使得每次弹出堆顶都能快速获取当前单位售价最高的月饼,减少了全局排序的时间复杂度。

3. 空间-时间权衡(Space-Time Tradeoff)

思想:程序优化中,有时需要在空间复杂度和时间复杂度之间进行权衡,以找到最优的折中方案。

应用:

  • 通过最大堆管理月饼信息,减少了排序所需的时间,同时避免了额外的数据结构,这体现了在空间和时间上的优化选择。

4. 原地修改(In-place Modification)

思想:在保证正确性的前提下,通过直接在原始数据结构上进行修改,减少额外的空间开销。

应用:

  • 使用负值堆构建最大堆,利用原有的列表存储计算结果,减少了不必要的内存使用。

5. 分治法(Divide and Conquer)

思想:通过将问题分解为多个子问题,分别解决子问题,最终合并结果来解决原问题。

应用:

  • 在排序的过程中,尽管我们采取的是贪心策略,但实际上是通过逐步解决局部最优问题来达到全局最优的效果。

6. 减少问题规模(Reduce Problem Size)

思想:通过每一步操作减少问题的规模,逐步逼近问题的解。

应用:

每次弹出堆顶元素(即单位售价最高的月饼),并更新市场需求量D,逐步减少问题规模,最终达到停止条件。


举一反三

理解编程中的哲学和思想能够帮助更好地解决问题和优化代码。以下是一些技巧和建议,帮助你在实际编程中运用这些思想,并举一反三。

1. 贪心算法(Greedy Algorithm)

技巧:

  • 识别贪心选择性质:在每一步选择中,找出当前最优的选择,并验证该选择是否能构成全局最优解。
  • 局部最优到全局最优:确保每一步的局部最优选择不会影响全局最优解的实现。

应用:

  • 优先考虑当前最具收益的操作,例如选择单位售价最高的月饼。
  • 在路径规划或调度问题中,优先选择代价最小的路径或任务。

2. 优先队列(Priority Queue)

技巧:

  • 动态管理:利用堆(或优先队列)在动态环境中快速获取当前最优解。
  • 堆的操作:熟练掌握堆的插入、删除、和调整操作,确保高效管理优先级。

应用:

  • 任务调度:使用优先队列管理任务,动态选择最优任务执行。
  • 网络流量管理:在网络路由中使用优先队列选择最优路径。

3. 空间-时间权衡(Space-Time Tradeoff)

技巧:

  • 缓存与存储:利用缓存(如动态规划中的记忆化)减少重复计算,但需考虑空间开销。
  • 预计算:预先计算并存储常用结果,换取运行时的计算效率。

应用:

  • 动态规划:通过存储子问题的解来提高效率。
  • 数据处理:在大数据处理中,通过预计算关键数据减少实时计算开销。

4. 原地修改(In-place Modification)

技巧:

  • 原地算法:设计算法时尽量在原数据结构上进行修改,减少额外空间占用。
  • 指针或索引操作:使用指针或索引直接操作数组和链表,提高效率。

应用:

  • 排序算法:如快速排序、堆排序等,尽量使用原地排序。
  • 数组处理:在数组中进行元素交换或重排时,尽量避免创建额外的数组。

5. 分治法(Divide and Conquer)

技巧:

  • 问题分解:将复杂问题分解为若干个子问题,分别解决后合并结果。
  • 递归思维:利用递归函数解决子问题,注意基准条件和递归关系。

应用:

  • 快速排序和归并排序:分解数组,再递归排序。
  • 大整数乘法:将大整数分解为较小整数计算再合并。

6. 减少问题规模(Reduce Problem Size)

技巧:

  • 逐步逼近:通过每一步操作逐步减少问题规模,直至问题解决。
  • 迭代改进:在每次迭代中改进结果,逐步达到最终解。

应用:

  • 递归算法:通过递归调用逐步减少问题规模。
  • 二分查找:每次缩小搜索范围,逐步逼近目标值。

具体技巧和示例:

  1. 动态规划与记忆化:
    • 识别子问题,存储中间结果。
    • 如计算斐波那契数列,避免重复计算。
  2. 滑动窗口:
    • 通过调整窗口范围高效处理连续子数组问题。
    • 如找到数组中和为目标值的连续子数组。
  3. 双指针:
  • 通过双指针遍历数组,解决合并、查找等问题。
  • 如合并两个有序数组。

总结

通过理解和运用这些编程思想和哲学,可以在解决问题时更具创造性和高效性。关键在于多加练习,逐步培养敏锐的算法设计和优化思维。


感谢。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小邪大佬最新版微信hook

目前小邪大佬已经更新到最新版本微信hook了。 /发送文件 BOOL SendCdnFilePbMsg(string sendId, string cdnkey, string aes_key,string file_name,string md5, int size, string syncKey) {FileMessage sfm;sfm.set_file_id(cdnkey);sfm.set_size(size);sfm.set_aes_key(aes_…

【计算机毕业设计】基于SSM++jsp的在线云音乐系统【源码+lw+部署文档】

目录 摘 要 ABSTRACT 第1章 绪论 1.1背景及意义 1.2 国内外研究概况 1.3 研究的内容 第2章 相关技术 2.1 JSP技术介绍 2.2 JAVA简介 2.3 MyEclipse开发环境 2.4 Tomcat服务器 2.5 MySQL数据库 2.6 SSM三大框架 第3章 系统分析 3.1 需求分析 3.2 系统可行性分析 3.2.1技术可行性…

CANDela studio基础使用

ECU Information 可以修改ECU的名称 里面有个Supported Interfaces&#xff0c;可以在CDDT里面选择支持的通讯接口 可以在tools下面新建internface&#xff0c;也可以从其他CDDT文件里面复制过来&#xff0c;复制的时候注意要另外将里面的参数再复制一次。 也可以在这里点击新…

云原生架构相关技术_4.服务网格

1.技术特点 服务网格&#xff08;ServiceMesh&#xff09;是分布式应用在微服务软件架构之上发展起来的新技术&#xff0c;旨在将那些微服务间的连接、安全、流量控制和可观测等通用功能下沉为平台基础设施&#xff0c;实现应用与平台基础设施的解耦。这个解耦意味着开发者无需…

多输入多输出 | MATLAB实现PSO-SVM粒子群优化支持向量机多输入多输出

多输入多输出 | MATLAB实现PSO-SVM粒子群优化支持向量机多输入多输出 目录 多输入多输出 | MATLAB实现PSO-SVM粒子群优化支持向量机多输入多输出预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 多输入多输出 | MATLAB实现PSO-SVM粒子群优化支持向量机多输入多输出…

Ethercat设备 转 成profinet IO协议项目案例

1 案例说明 设置网关采集EtherCAT设备数据把采集的数据转成profinet IO协议转发给其他系统。 2 准备工作 3. 仰科网关。支持采集EtherCAT设备数据&#xff0c;profinet IO协议转发。 4. 电脑。IP设置成192.168.1.198&#xff0c;和网关在同一个网段。 5. 网线、12V电源。 3 …

Qt xml学习之calculator-qml

1.功能说明&#xff1a;制作简易计算器 2.使用技术&#xff1a;qml,scxml 3.项目效果&#xff1a; 4.qml部分&#xff1a; import Calculator 1.0 //需要引用对应类的队友版本 import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 1.4 import QtScxml…

shopee签名x-sap-ri、x-sap-sec算法还原

最新版签名&#xff0c;免账号登录成功率百分百&#xff0c;需要可d 两种方式base64 MTQzMDY0OTc3OA QXVndXN0MjItZnF4

内存取证例题及Volatility2.6的使用(含命令详细解析)

文章目录 一、背景二、什么是内存取证&#xff1f;三、参考文章四、工具及题目五、解析1、哪个Volatility配置文件最适合这台机器&#xff1f;拓展1.1 2、获取镜像时有多少个进程在运行&#xff1f;拓展1.2 3、cmd.exe的进程ID是什么&#xff1f;4、最可疑的进程名称是什么&…

轻松实现PDF文件的在线浏览

福昕软件最近发布了一款名为Cloud API的产品&#xff0c;通过几行代码即可轻松实现PDF文件的在线浏览。先一睹为快吧。 简介 先看看产品官网&#xff1a;福昕 Cloud API Cloud API包括两个形态产品&#xff0c;一个是在线的PDF查看工具&#xff0c;叫PDF Embed API,另外一个…

面试题 17.05. 字母与数字(前缀和)

给定一个放有字母和数字的数组&#xff0c;找到最长的子数组&#xff0c;且包含的字母和数字的个数相同。 返回该子数组&#xff0c;若存在多个最长子数组&#xff0c;返回左端点下标值最小的子数组。若不存在这样的数组&#xff0c;返回一个空数组。 示例 1: 输入: ["…

【并发程序设计】13.信号机制

13.信号机制 概念&#xff1a; 信号机制是Unix、类Unix以及其他POSIX兼容的操作系统中的一种进程间通讯方式&#xff0c;它允许进程在发生特定事件时接收通知。 信号机制是操作系统中的一个重要概念&#xff0c;它提供了一种异步的通知机制&#xff0c;用于在进程之间传递消…

每日一题——Python实现PAT甲级1042 Shuffling Machine(举一反三+思想解读+逐步优化)

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 功能分析 时间复杂度 空间复杂度 总结 代码点评 我要更强 优化方向 …

数据库开发-Mysql03

目录 1. 多表查询 1.1 概述 1.1.1 数据准备 1.1.2 介绍 1.1.3 分类 1.2 内连接 1.3 外连接 1.4 子查询 1.4.1 介绍 1.4.2 标量子查询 1.4.3 列子查询 1.4.4 行子查询 1.4.5 表子查询 1.5 案例 2. 事务 2.1 介绍 2.2 操作 2.3 四大特性 3. 索引 3.1 介绍 3…

光伏企业供应链采购数字化转型升级路径

随着中国光伏行业引领全球&#xff0c;光伏行业竞争激烈。在供应链方面的处理能力也需要有更好的提升。本身光伏企业采购体系依赖传统采购方式&#xff0c;除了需要采购人员耗费大量的时间做供应商的背景调查之外&#xff0c;大量环节却依靠人工线下的方式完成&#xff0c;比如…

微服务 feign-gateway

早期微服务跨集群调用 使用的是Eureka 和RestTemplate&#xff0c;这种写法虽然可以解决服务之间的调用问题 ,但是随着服务的增多&#xff0c;实例变动&#xff0c;早期的写法相当于把请求方式&#xff0c;请求地址&#xff0c;参数写死了&#xff0c;耦合度太高&#xff0c;参…

OpenAI助手API接入-问答对自动生成

支持GPT-3.5-Turbo, GPT-4o, GPT-4-Turbo import json import openai from pathlib import Path import os client openai.OpenAI(base_urlbase_url, api_keyapi_key) file client.files.create( fileopen("H3.pdf", "rb"), purposeassistants ) …

Matplotlib | 绘制柱状图

简介 安装 Matplotlib 开始绘制 简单柱状图 改变颜色 改变纹理 改变边框样式 改变透明度 改变柱子宽度 改变图表标题 ​编辑 并列柱状图 横向柱状图 堆叠柱状图 更多函数 简介 柱状图&#xff08;Bar chart&#xff09;&#xff0c;是一种以长方形的长度为变量的…

重庆人文科技学院建立“软件安全产学研基地”,推动西南地区软件安全发展

5月29日&#xff0c;重庆人文科技学院与开源网安签订了《产学研校企合作协议》&#xff0c;并举行了“重庆人文科技学院产学研基地”授牌仪式&#xff0c;此次合作不仅深化了双方在软件安全领域的产学研紧密联结&#xff0c;更是对川渝乃至西南地区软件供应链安全发展起到重要的…

缓冲区溢出攻击

缓冲区溢出攻击 缓冲区溢出概述基础概念缓冲区溢出根源缓冲区溢出危害性&普遍性 缓冲区溢出攻击原理内存分配模式缓冲区溢出攻击缓冲区溢出攻击原理缓冲区溢出攻击分类堆栈溢出堆栈相关知识攻击原理 堆溢出攻击堆简介堆溢出DWORD SHOOT BSS段溢出 缓冲区溢出攻击防御措施防…