每日一题——Python实现PAT甲级1116 Come on! Let‘s C(举一反三+思想解读+逐步优化)五千字好文

一个认为一切根源都是“自己不够强”的INTJ
个人主页:用哲学编程-CSDN博客
专栏:每日一题——举一反三
Python编程学习
Python内置函数
Python-3.12.0文档解读
目录
我的写法
代码点评
时间复杂度分析
空间复杂度分析
总结
我要更强
优化思路
优化后的代码
时间复杂度分析
空间复杂度分析
优化总结
哲学和编程思想
1. 时间复杂度与空间复杂度的权衡
哲学思想:资源优化(Resource Optimization)
2. 使用合适的数据结构
哲学思想:选择合适工具(Right Tool for the Job)
3. 减少不必要的操作
哲学思想:简洁性(Simplicity)
4. 一次性读取和输出数据
哲学思想:批处理(Batch Processing)
5. 高效的算法
哲学思想:算法优化(Algorithm Optimization)
6. 幂等性和状态管理
哲学思想:幂等性(Idempotency)与状态管理(State Management)
总结
举一反三
1. 优化时间和空间复杂度
技巧:
思想:
2. 使用合适的数据结构
技巧:
思想:
3. 减少不必要的操作
技巧:
思想:
4. 批处理和减少I/O操作
技巧:
思想:
5. 高效算法选择
技巧:
思想:
6. 幂等性和状态管理
技巧:
思想:
举一反三的应用
总结
题目链接


我的写法
import sys
import mathdef is_prime(num):if num <= 1:return Falseif num <= 3:return Trueif num % 2 == 0 or num % 3 == 0:return Falsefor i in range(5, int(math.sqrt(num)) + 1, 6):if num % i == 0 or num % (i + 2) == 0:return Falsereturn Trueinput = sys.stdin.read
data = input().split()
N = int(data[0])
ranklist_ids = {}
for i in range(1, N + 1):ranklist_ids[data[i]] = ichecked_ids = set()
K = int(data[N + 1])output = []for i in range(N + 2, K + N + 2):query_id = data[i]if query_id in ranklist_ids:if query_id in checked_ids:output.append(f"{query_id}: Checked")else:rank = ranklist_ids[query_id]if rank == 1:output.append(f"{query_id}: Mystery Award")elif is_prime(rank):output.append(f"{query_id}: Minion")else:output.append(f"{query_id}: Chocolate")checked_ids.add(query_id)else:output.append(f"{query_id}: Are you kidding?")# 将所有输出一次性打印,减少 I/O 操作
sys.stdout.write("\n".join(output) + "\n")

代码点评
这段代码实现了对一组ID的排名查询,并根据排名给出不同的反馈。代码结构清晰,使用了适当的数据结构(字典和集合)来优化查询效率。下面是对代码的详细点评:
- 模块导入:
- 使用了sys和math模块,分别用于处理输入输出和数学运算,这是合理的。
- 函数定义:
- is_prime函数用于判断一个数是否为素数,使用了优化的算法,只检查到平方根,减少了不必要的计算。
- 数据处理:
- 使用sys.stdin.read一次性读取所有输入,减少了I/O操作的次数。
- 将输入数据分割后存储在列表data中,方便后续处理。
- 数据结构使用:
- 使用字典ranklist_ids存储ID和其对应的排名,利用字典的快速查找特性,提高了查询效率。
- 使用集合checked_ids存储已检查的ID,避免了重复检查,优化了处理流程。
- 输出处理:
- 将所有输出存储在列表output中,最后一次性输出,减少了I/O操作的次数,提高了效率。
时间复杂度分析
- 读取输入:O(N + K),其中N是排名列表中的ID数量,K是查询的ID数量。
- 构建排名字典:O(N),遍历排名列表一次。
- 查询处理:O(K),每个查询操作的时间复杂度是O(1),因为使用了字典和集合。
- 输出:O(N + K),构建输出列表的时间。
总时间复杂度为O(N + K)。
空间复杂度分析
- 存储输入数据:O(N + K),需要存储所有输入数据。
- 排名字典:O(N),存储所有排名信息。
- 已检查ID集合:O(K),最多存储K个已检查的ID。
- 输出列表:O(K),存储所有查询结果。
总空间复杂度为O(N + K)。
总结
这段代码在处理大量数据时表现良好,时间复杂度和空间复杂度都与输入规模成线性关系,效率较高。代码结构清晰,使用了合适的数据结构和算法,是一段高质量的代码。
我要更强
这段代码已经相对高效,不过还是可以在一些细节上进行优化,以进一步提升性能。以下是一些可能的优化方法:
- 减少不必要的操作:在查询阶段直接读取和处理数据,而不是预先存储所有ID。
- 优化素数判断函数:虽然当前实现已经较优化,但我们可以进一步减少检查次数。
以下是经过优化的完整代码和分析:
优化思路
- 减少内存占用:只在需要时存储数据,而不是预先存储所有ID和排名。
- 优化素数判断:利用更高效的素数判断算法。
优化后的代码
python复制
import sys
import mathdef is_prime(num):"""判断一个数是否为素数"""if num <= 1:return Falseif num <= 3:return Trueif num % 2 == 0 or num % 3 == 0:return Falsefor i in range(5, int(math.sqrt(num)) + 1, 6):if num % i == 0 or num % (i + 2) == 0:return Falsereturn True# 从标准输入读取所有数据
input = sys.stdin.read
data = input().split()N = int(data[0]) # 排名列表中的ID数量
ranklist_ids = {data[i]: i for i in range(1, N + 1)} # 构建ID和排名的字典
checked_ids = set() # 存储已检查的ID
K = int(data[N + 1]) # 查询的ID数量output = [] # 用于存储最终输出的结果列表# 处理所有查询
for i in range(N + 2, N + 2 + K):query_id = data[i]if query_id in ranklist_ids:if query_id in checked_ids:output.append(f"{query_id}: Checked")else:rank = ranklist_ids[query_id]if rank == 1:output.append(f"{query_id}: Mystery Award")elif is_prime(rank):output.append(f"{query_id}: Minion")else:output.append(f"{query_id}: Chocolate")checked_ids.add(query_id)else:output.append(f"{query_id}: Are you kidding?")# 将所有输出结果一次性打印,减少I/O操作
sys.stdout.write("\n".join(output) + "\n")
时间复杂度分析
- 读取输入:O(N + K),其中N是排名列表中的ID数量,K是查询的ID数量。
- 构建排名字典:O(N),遍历排名列表一次。
- 查询处理:O(K),每个查询操作的时间复杂度是O(1),因为使用了字典和集合。
- 输出:O(K),构建输出列表的时间。
总时间复杂度为O(N + K)。
空间复杂度分析
- 存储输入数据:O(N + K),需要存储所有输入数据。
- 排名字典:O(N),存储所有排名信息。
- 已检查ID集合:O(K),最多存储K个已检查的ID。
- 输出列表:O(K),存储所有查询结果。
总空间复杂度为O(N + K)。
优化总结
通过以上优化,确保在时间和空间上的复杂度都保持在O(N + K)的水平,而代码的可读性和效率也得到了提升。这段优化后的代码更紧凑,并且在处理查询时更加直接。
哲学和编程思想
在优化这段代码的过程中,运用了多种编程思想和哲学,以提升代码的效率和可读性。以下是具体的分析:
1. 时间复杂度与空间复杂度的权衡
哲学思想:资源优化(Resource Optimization)
- 描述:在计算机科学中,时间和空间是两种重要的资源。通常情况下,优化一方面可能会牺牲另一方面,需要在两者之间找到一个平衡点。
- 应用:我们在优化过程中,确保时间复杂度和空间复杂度都保持在O(N + K)的水平,既保证处理速度,又不浪费内存资源。
2. 使用合适的数据结构
哲学思想:选择合适工具(Right Tool for the Job)
- 描述:不同的数据结构有不同的特点和适用场景,选择合适的数据结构能够显著提升程序的效率。
- 应用:使用了字典(
dict)来存储ID与排名的映射,以实现快速查找操作(O(1)时间复杂度);使用集合(set)来存储已检查的ID,以实现快速存在性检查(O(1)时间复杂度)。
3. 减少不必要的操作
哲学思想:简洁性(Simplicity)
- 描述:减少不必要的步骤和操作,使代码更加简洁高效。
- 应用:在查询阶段直接处理数据,而不是预先存储所有ID,这样减少了内存占用,并避免了多次遍历数据。
4. 一次性读取和输出数据
哲学思想:批处理(Batch Processing)
- 描述:通过一次性读取和处理大量数据,减少频繁I/O操作,提升程序运行效率。
- 应用:使用
sys.stdin.read一次性读取所有输入数据,使用sys.stdout.write一次性输出所有结果,减少了多次I/O操作的开销。
5. 高效的算法
哲学思想:算法优化(Algorithm Optimization)
- 描述:选择高效的算法来解决问题,减少计算量和时间开销。
- 应用:在素数判断中,使用优化的算法,仅检查到平方根且跳过明显非素数的数(如偶数和3的倍数),减少了不必要的计算。
6. 幂等性和状态管理
哲学思想:幂等性(Idempotency)与状态管理(State Management)
- 描述:在重复操作中确保操作结果不变,这样可以避免重复计算和不一致的结果。
- 应用:通过集合
checked_ids记录已检查的ID,保证每个ID只处理一次,避免重复处理,确保程序状态一致性。
总结
通过运用以上哲学和编程思想,在优化过程中,既提升了代码的效率,又保持了代码的简洁和可维护性。这些思想不仅可以应用在这段代码中,对于其他编程任务同样适用,是编写高质量代码的重要原则。
举一反三
理解并应用编程哲学和思想能够大幅提升你的代码质量和效率。以下是一些常见的编程技巧和实践,每个技巧背后都有相关的哲学思想,希望能在不同的编程场景中灵活应用。
1. 优化时间和空间复杂度
技巧:
- 时间复杂度:在选择算法时,优先考虑时间复杂度较低的算法。例如,尽量避免使用O(n^2)的算法(如嵌套循环),可以考虑使用分治法、动态规划等优化算法。
- 空间复杂度:尽量减少不必要的数据存储,使用合适的数据结构(如数组、链表、哈希表)来优化内存使用。
思想:
- 资源优化:在开发过程中,始终考虑如何在时间和空间之间找到平衡点。
2. 使用合适的数据结构
技巧:
- 哈希表:用于快速查找、插入和删除操作。
- 数组/列表:用于需要快速访问元素的场景。
- 队列/栈:用于需要先进先出(FIFO)或后进先出(LIFO)操作的场景。
- 树/图:用于表示层次结构或连接关系的场景。
思想:
- 选择合适工具:根据具体问题选择最合适的数据结构,以提升程序的性能和可读性。
3. 减少不必要的操作
技巧:
- 懒加载:仅在需要时才初始化或计算数据,避免提前占用资源。
- 缓存:对于重复计算的结果进行缓存,避免多次计算相同的结果。
- 优雅的条件检查:尽量简化条件检查,避免多余的判断。
思想:
- 简洁性:代码应尽量简洁,减少不必要的复杂性。
4. 批处理和减少I/O操作
技巧:
- 批量读取和写入:尽量一次性读取或写入大量数据,减少I/O操作的次数。
- 缓冲区使用:使用缓冲区来提高I/O操作的效率。
思想:
- 批处理:通过一次性处理大量数据,提高程序的整体效率。
5. 高效算法选择
技巧:
- 分治法:将问题分解为规模较小的子问题再逐步解决,如快速排序、归并排序。
- 动态规划:通过记录中间结果,避免重复计算,如斐波那契数列、背包问题。
- 贪心算法:在每一步选择中做出局部最优选择,期望最终结果是全局最优,如最小生成树、活动选择问题。
思想:
- 算法优化:选择适合的高效算法解决问题,减少计算开销。
6. 幂等性和状态管理
技巧:
- 幂等操作:设计函数和方法时,确保对同一输入多次调用结果不变,常用于接口设计和数据库操作。
- 状态管理:使用状态管理工具(如Redux、Vuex)集中管理应用状态,避免不同部分状态不一致。
思想:
- 幂等性和状态管理:确保程序在重复操作中保持一致性,避免不必要的副作用。
举一反三的应用
-
优化查询操作:
- 思想:选择合适的数据结构(如哈希表)进行快速查找。
- 应用:在需要反复查找的场景中,优先使用哈希表来存储和查找数据。
-
减少重复计算:
- 思想:使用缓存(如Memoization)记录中间结果。
- 应用:在递归算法中,通过缓存已计算的结果,避免重复计算,提高效率。
-
简化代码逻辑:
- 思想:简化条件判断,减少嵌套层次。
- 应用:在复杂的条件判断中,尽量将相似的条件合并,或重构为多个简单函数,提高代码可读性。
-
批量操作:
- 思想:尽量一次性处理大量数据,减少I/O操作。
- 应用:在处理大文件或大量网络请求时,采用批量读取或写入的方式,减少I/O次数,提高效率。
总结
通过理解并应用这些编程技巧和思想,可以在不同的编程场景中灵活运用,提升代码的效率和可读性。每种技巧背后的思想都是编程中的基本原则,掌握这些原则将帮助在面对复杂问题时,能够更自如地找到最优解。
相关文章:
每日一题——Python实现PAT甲级1116 Come on! Let‘s C(举一反三+思想解读+逐步优化)五千字好文
一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 代码点评 时间复杂度分析 空间复杂度分析 总结 我要更强 优化思路 优化…...
spring-data-mongodb版本兼容问题
spring-data-mongodb与mongodb驱动有兼容性问题,不匹配会报NoSuchMethod异常,mongodb的java驱动包在4.0之后由mongodb-java-driver更名为mongodb-driver-sync。 spring-data-mongodb包依赖中有mongodb-driver-core,但缺诸如MongoCollection等…...
Java的核心类库
引言 在Java编程中,熟练掌握常用类与对象操作是开发的基础。Java的核心类库提供了丰富的功能,可以帮助开发者高效地处理各种编程任务。本文将详细介绍Java字符串操作、集合框架、日期与时间处理等内容,并通过图表和表格进行总结与示范。 字符…...
NSS题目练习9
[极客大挑战 2020]welcome 界面打开后一片空白,查看题目描述,翻译过来是 1.除了GET请求方法,还有一种常见的请求方法… 2.学习一些关于sha1和array的知识。 3.更仔细地检查phpinfo,你会发现标志在哪里。 补充: sh…...
JS 【算法】二分查找
使用场景 在有序数组中查找目标元素 const arr [1, 2, 3, 4, 5, 6, 7, 8, 9] const target 2 console.log(binarySearch1(arr, target)) console.log(binarySearch2(arr, target))循环实现 function binarySearch1(arr, target) {const length arr.lengthif (length 0) re…...
前端工程化工具系列(十四)—— Webpack(v5.91.0):应用模块打包器与构建工具
Webpack 是用于现代 JavaScript 应用程序的静态模块打包器。 当 webpack 处理应用程序时,它会在内部构建一个依赖关系图,该图映射项目所需的每个模块最终会生成一个或多个包。 1 概念 1.1 modules Webpack 中,无论是 JS 、CSS 还是图片等&…...
ThinkPHP+Bootstrap简约自适应网址导航网站源码
使用 ThinkPHPbootstrap 开发,后台采用全局 ajax 无刷新加载,前后台自适应,前台页面非常简洁适合自己收藏网站或做导航网站。 搭建教程: 1.整个主机 2.绑定解析域名 3.上传源码,解压 把解压出来的 nav.sql 文件导入数…...
Flutter 使用ffigen生成ffmpeg的dart接口
Flutter视频渲染系列 第一章 Android使用Texture渲染视频 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频 第四章 全平台FFICustomPainter渲染视频 第五章 Windows使用Native窗口渲染视频 第六章 桌面端使用texture_rgba_renderer渲染视频 第七章 使用ff…...
(message): No CUDA toolset found.
解决方法: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\extras\visual_studio_integration\MSBuildExtensions\ 下的4个文件 复制到 D:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VC\v170\BuildCustomizations\下。…...
【python】邮箱正则验证
当然可以。以下是一个使用Python正则表达式的例子,用于检查一个字符串是否是一个有效的电子邮件地址: import re def is_valid_email(email):regex r^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$return bool(re.match(regex, email)) # 测试电子邮件…...
深度学习(四)——torchvision中数据集的使用
1. 参数详解 torchvision中每个数据集的参数都是大同小异的,这里只介绍CIFAR10数据集 该数据集的数据格式为PIL格式 class torchvision.datasets.CIFAR10(root:str,train:boolTrue,transform:Optional[Callable]None,target_transform:Optional[Callable]None,do…...
【全开源】图书借阅管理系统源码(ThinkPHP+FastAdmin)
📚图书借阅管理系统:打造你的私人图书馆 一款基于ThinkPHPFastAdmin开发的简易图书借阅管理系统,一款轻量级的图书借阅管理系统,具有会员管理,图书管理,借阅及归还管理,会员充值等基本功能&…...
Mysql中使用where 1=1有什么问题吗
昨天偶然看见一篇文章,提到说如果在mysql查询语句中,使用where 11会有性能问题?? 这着实把我吸引了,因为我项目中就有不少同事,包括我自己也有这样写的。为了不给其他人挖坑,赶紧学习一下&…...
中心极限定理的MATLAB例
独立同分布的中心极限定理: 设 X 1 , X 2 , … , X n X_1, X_2, \ldots, X_n X1,X2,…,Xn 是独立同分布的随机变量序列,且 E ( X i ) μ E(X_i) \mu E(Xi)μ, D ( X i ) σ 2 > 0 D(X_i) \sigma^2 > 0 D(Xi)σ2>0&a…...
定义input_password函数,提示用户输入密码.如果用户输入长度<8,抛出异常,如果用户输入长度>=8,返回输入的密码
def input_password(password):str1passwordlen1len(str1)try:if len1<8:raise ValueError("密码长度不能小于8")else:return print(f"你的密码为:{password},请确认")except ValueError as e:print(f":Error is {e}")number1input("请…...
【深度学习】IP-Adapter 和 InstantID 的核心机制比较
IP-Adapter 和 InstantID 是两个在图像生成中具有不同优势和应用场景的模型。以下是这两个模型的区别及其理论分析。 IP-Adapter 特点: 图像提示能力: IP-Adapter 通过引入图像提示能力,使得预训练的文本到图像扩散模型可以接受图像作为提示,从而生成…...
JEPaaS 低代码平台 j_spring_security_check SQL注入漏洞复现
0x01 产品简介 JEPaaS是一款优秀的软件平台产品,可视化开发环境,低代码拖拽式配置开发,操作极其简单,可以帮助解决Java项目80%的重复工作,让开发更多关注业务逻辑,大大提高开发效率,能帮助公司大幅节省人力成本和时间成本,同时又不失灵活性。适用于搭建 OA、ERP、CRM、…...
天锐绿盾 | 无感知加密软件、透明加密系统、数据防泄漏软件
摘要:文件加密软件,包含禁止非授权的文件泄密和抄袭复制解决方案即使被复制泄密都是自动加密无法阅读,透明加密,反复制软件,内网监控,文件加密,网络安全方案,透明文件加密,加密文件,图纸加密,知识产权保护,加密数据; 通过绿盾信息安全管理软件,系统在不改…...
kubernetes(k8s)集群部署(2)
目录 k8s集群类型 k8s集群规划: 1.基础环境准备: (1)保证可以连接外网 (2)关闭禁用防火墙和selinux (3)同步阿里云服务器时间(达到集群之间时间同步) &…...
Git操作指南
1、提交代码操作 拉取线上分支,防止本地代码提交冲突 git pull origin dev git add . git commit -m “给本次提交添加注释” git push origin dev 2、打分支并切换分支 git checkout -b 新建并切换到新分支 切换到主分支 git checkout main git merge dev git p…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
Unity VR/MR开发-VR开发与传统3D开发的差异
视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...
