每日一题——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:  # 如果市场需求量已经满足,退出循环breakif 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. 双指针:
  • 通过双指针遍历数组,解决合并、查找等问题。
  • 如合并两个有序数组。

总结

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


感谢。

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

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

相关文章

【一步一步了解Java系列】:子类继承以及代码块的初始化

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 个人主页&#xff1a;Gu Gu Study专栏&#xff1a;一步一步了解Java 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xff1a;小闭 …

分享一个在linux中运行通义千问的方法

分享一个在linux中和通义千问交互的方法 效果展示: 整体步骤 分享一个在linux中和通义千问交互的方法效果展示:一、在阿里云appflow控制台创建连接流1、通过以下地址,在灵积平台创建个API-KEY,用于通义千问的连接凭证2、点击连接流-创建连接流3、第一步选择webhook4.第二步…

nginx和proxy_protocol协议

目录 1. 引言2. HTTP server的配置3. Stream server的配置3.1 作为proxy_protocol的前端服务器3.2 作为proxy_protocol的后端服务器1. 引言 proxy_protocol 是haproxy开发的一种用于在代理服务器和后端服务器之间传递客户端连接信息的协议。使用 proxy_protocol 的主要优势是能…

【ai】livekit服务本地开发模式1:example app信令交互详细流程

文档要安装git lfs 下载当前最新版本1.6.1windows版本:启动dev模式 服务器启动 (.venv) PS D:\XTRANS\pythonProject\LIVEKIT> cd .

VS2022+QT5.15.2+MySQL8.4大集合

网上的教程都建议用Qt5&#xff0c;不要用6&#xff0c;不死心的尝试了整整一天失败了&#xff0c;乖乖用回5&#xff0c;qt5需要编译一下生成mysql的动态和静态库 1. mysql8.4安装 下载社区开发版&#xff0c;注意要64位 https://dev.mysql.com/downloads/mysql/ 配置一下数…

安卓SystemServer进程详解

目录 一、概述二、源码分析2.1 SystemServer fork流程分析2.1.1 [ZygoteInit.java] main()2.1.2 [ZygoteInit.java] forkSystemServer()2.1.3 [Zygote.java] forkSystemServer()2.1.4 [com_android_internal_os_Zygote.cpp]2.1.5 [com_android_internal_os_Zygote.cpp] ForkCom…

CANDela studio基础使用

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

倪师哲学。能让我好,我就接受

还有有些人更搞笑的是&#xff0c;把自己的行为啊&#xff0c;建立在别人的基础之上&#xff0c;如果那个人么样对我&#xff0c;我肯定能怎么样对这个人。 生而为人呐&#xff0c;你是一个独立的人&#xff0c;不要去总是拿着各种各样的前提&#xff0c;来限制了自己个人的成长…

打造你的专属Vue组件:超实用“手机号、邮箱、身份证号加密显示组件“实战

随着Web应用程序的发展&#xff0c;我们经常需要处理用户敏感信息&#xff0c;如手机号码和身份证号码。为了保护用户隐私&#xff0c;我们需要在前端对这些信息进行加密处理&#xff0c;以避免直接暴露在页面上。在这篇博客中&#xff0c;我们将介绍如何使用Vue 3.0单文件组件…

CATO原理中的数学与魔术(十一)——Parity Principle及其应用二:集合的可视化...

早点关注我&#xff0c;精彩不错过&#xff01; 上篇文章中&#xff0c;我们已经进入了CATO原理魔术介绍的深水区&#xff0c;是第3个系列Parity Principle中集合性质的章节&#xff0c;聊到了关于张数和求和集合性质&#xff0c;并对性质之间的偏序关系&#xff0c;性质之间的…

three.js官方案例(animation / keyframes)webgl_animation_keyframes.html学习

目录 ​编辑 1 PMREMenerator 1.1 构造函数 1.2 fromScene方法 2 AnimationMixer 3 animal1.html全部 4 animal1.js全部 1 PMREMenerator 此类生成预过滤的 Mipmapped 辐射环境贴图 &#xff08;PMREM&#xff09; 来自 cubeMap 环境纹理。这允许不同的级别 的模糊&…

桶形畸变和枕形畸变

桶形畸变和枕形畸变是两种常见的光学畸变现象&#xff0c;主要发生在使用广角镜头或远摄镜头拍摄时。这些畸变是因为镜头的光学特性不能完美地将光线汇聚到一个共同的焦点上&#xff0c;导致图像的不同部分在形状上发生扭曲。下面分别对这两种畸变进行详细描述&#xff1a; 桶…

快手万合通脚本,磁力广告挂机变现项目,号称单窗口日收益10+(教程+软件)

在这个项目中&#xff0c;我们采用一种简便的方法来获取额外收入。比如&#xff1a; 1. 主账号准备&#xff1a;首先&#xff0c;确保拥有一个已开通磁力万合功能的快手主账号。账号需拥有至少一万粉丝&#xff0c;以确保广告收益。 2. 创建快手小号&#xff1a;无需粉丝基础…

每日一题《leetcode--LCR 021.删除链表的倒数第N个结点》

https://leetcode.cn/problems/SLwz0R/ 这道题我们可以设一个哨兵位&#xff0c;然后把要遍历链表的结点指向该哨兵位。最后用for循环将指针指向要删除结点的前一个。 struct ListNode* removeNthFromEnd(struct ListNode* head, int n){struct ListNode* dummy malloc(sizeof…

什么是成就动机?如何判断人的成就动机?

什么是成就动机&#xff1f; 成就动机指的是一个人追求成就的心理&#xff0c;对成就&#xff08;成绩&#xff0c;目标&#xff09;的渴望心理&#xff0c;成就动机促进我们实现个人价值&#xff0c;完成工作当中的任务&#xff0c;始终被成就动机驱使的人往往懂得吃苦耐劳&a…

通过强化学习策略进行特征选择

特征选择是构建机器学习模型过程中的决定性步骤。为模型和我们想要完成的任务选择好的特征&#xff0c;可以提高性能。 如果我们处理的是高维数据集&#xff0c;那么选择特征就显得尤为重要。它使模型能够更快更好地学习。我们的想法是找到最优数量的特征和最有意义的特征。 …

wampserver安装与汉化

wampserver安装与汉化 文章目录 wampserver安装与汉化一、安装二、汉化1.升级软件并安装补丁 介绍&#xff1a; WampServer是一款由法国人开发的Apache Web服务器、PHP解释器以及MySQL数据库的整合软件包。免去了开发人员将时间花费在繁琐的配置环境过程&#xff0c;从而腾出更…

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

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

stm32F4的时钟树

时钟其实就是单片机的心脏。首先我们的高速外部时钟&#xff08;HES&#xff09;&#xff0c;看名字就可知道外部高速时钟是由外部所提供的其是高速的&#xff0c;其具体可以是有源晶振或者无源晶振所提供的时钟。而在时钟树图中我们从OSC_IN、OSC_OUT进入&#xff0c;然后经过…

【项目管理知识】项目质量管理措施

1、持续改进&#xff08;PDCA&#xff09; 戴明循环或称PDCA循环、PDSA循环。戴明循环的研究起源于20世纪20年代&#xff0c;先是有着“统计质量控制之父”之称的著名的统计学家沃特阿曼德休哈特&#xff08;Walter A. Shewhart&#xff09;在当时引入了“计划-执行-检查&…