每日一题——Python代码实现PAT乙级1082 射击比赛(举一反三+思想解读+逐步优化)四千字好文


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

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

Python-3.12.0文档解读

目录

我的写法

代码分析

代码步骤

时间复杂度分析

空间复杂度分析

总结

我要更强

时间复杂度分析

空间复杂度分析

总结

哲学和编程思想

KISS原则(Keep It Simple, Stupid):

YAGNI原则(You Ain't Gonna Need It):

效率优化:

数据结构的选择:

函数式编程思想:

抽象和模块化:

实用主义:

举一反三


题目链接:https://pintia.cn/problem-sets/994805260223102976/exam/problems/type/7?problemSetProblemId=994805260990660608&page=0

我的写法

n=int(input())
player_scores=[]
for i in range(n):
    player_score=input().split()
    player_score[1]=int(player_score[1])
    player_score[2]=int(player_score[2])
    player_scores.append([player_score[0],player_score[1]**2+player_score[2]**2])
    
ranking=sorted(player_scores,key=lambda x: x[1])
print(f"{ranking[0][0]} {ranking[-1][0]}")

代码分析

这段代码实现了射击比赛的排名功能,根据输入的运动员编号和射击坐标,计算每个运动员的得分(距离靶心的平方和),然后对运动员进行排序,最后输出得分最低(冠军)和最高(菜鸟)的运动员编号。

代码步骤
  1. 输入处理:
    • 读取运动员数量 n。
    • 循环读取每个运动员的信息,包括编号和射击坐标,计算得分(距离的平方和),并将编号和得分存储在列表 player_scores 中。
  2. 排序:
    • 使用 sorted() 函数对 player_scores 列表进行排序,排序的关键字是每个运动员的得分。
  3. 输出:
  • 输出得分最低的运动员编号(即排序后列表的第一个元素的编号)和得分最高的运动员编号(即排序后列表的最后一个元素的编号)。
时间复杂度分析
  1. 输入处理:
    • 读取 n 个运动员的信息,每个运动员的信息处理包括字符串分割和整数转换,时间复杂度为 O(n)。
  2. 排序:
    • 使用 sorted() 函数对包含 n 个元素的列表进行排序,时间复杂度为 O(n log n)。
  3. 输出:
  • 输出操作的时间复杂度为 O(1)。

总时间复杂度为 O(n + n log n),即 O(n log n)。

空间复杂度分析
  1. 存储运动员信息:
    • 使用列表 player_scores 存储所有运动员的编号和得分,空间复杂度为 O(n)。
  2. 其他变量:
  • 除了输入和输出的变量外,没有使用额外的数据结构,空间复杂度为 O(1)。

总空间复杂度为 O(n)。

总结

这段代码有效地解决了射击比赛的排名问题,时间复杂度主要受排序操作影响,为 O(n log n),空间复杂度为 O(n)。代码结构清晰,逻辑简单,适合处理中小规模的数据集。对于大规模数据集,可能需要考虑更高效的排序算法或数据结构来优化性能。


我要更强

为了优化时间复杂度和空间复杂度,我们可以考虑以下几点:

  1. 避免不必要的排序:我们只需要找到距离最小的和最大的,不需要对所有数据进行排序。
  2. 使用更有效的数据结构:例如,使用字典(dict)来存储运动员的编号和得分,可以快速查找。
  3. 减少内存分配:避免在循环中进行大量的列表追加操作,这可能会导致多次内存分配。

下面是优化后的代码:

# 读取运动员数量
n = int(input())

# 初始化字典存储运动员信息
player_scores = {}

# 读取每个运动员的信息并计算得分
for _ in range(n):
    # 读取一行输入,分割成列表
    player_info = input().split()
    # 运动员编号
    player_id = player_info[0]
    # 射击坐标
    x, y = map(int, player_info[1:])
    # 计算得分(距离的平方和)
    score = x**2 + y**2
    # 存储到字典中
    player_scores[player_id] = score

# 找到得分最小的运动员
min_score_player = min(player_scores, key=player_scores.get)
# 找到得分最大的运动员
max_score_player = max(player_scores, key=player_scores.get)

# 输出结果
print(f"{min_score_player} {max_score_player}")

时间复杂度分析

  1. 输入处理:
    • 读取 n 个运动员的信息,每个运动员的信息处理包括字符串分割和整数转换,时间复杂度为 O(n)。
  2. 查找最小和最大得分:
  • 使用 min() 和 max() 函数查找字典中的最小和最大值,时间复杂度为 O(n)。

总时间复杂度为 O(n)。

空间复杂度分析

  1. 存储运动员信息:
  • 使用字典 player_scores 存储所有运动员的编号和得分,空间复杂度为 O(n)。

总空间复杂度为 O(n)。

总结

这段优化后的代码避免了不必要的排序操作,使用字典来存储和快速查找运动员信息,有效地减少了时间复杂度和空间复杂度。时间复杂度从 O(n log n) 降低到 O(n),空间复杂度保持为 O(n)。这种优化特别适用于处理大规模数据集,可以显著提高程序的执行效率。


哲学和编程思想

优化这段代码所使用的方法体现了以下哲学和编程思想:

  1. KISS原则(Keep It Simple, Stupid):

    • 代码简洁明了,避免不必要的复杂性。例如,使用字典直接存储和查找运动员信息,而不是通过排序来找到最小和最大值。
  2. YAGNI原则(You Ain't Gonna Need It):

    • 只实现当前需要的功能,不预先实现未来可能需要的功能。在这个例子中,我们只关注找到最小和最大值的运动员,而不是对所有运动员进行排序。
  3. 效率优化:

    • 通过减少不必要的数据处理和排序,提高了程序的执行效率。这体现了对时间和空间复杂度的关注,是算法和数据结构设计中的重要思想。
  4. 数据结构的选择:

    • 使用字典(dict)作为数据结构,利用了字典在查找操作上的高效性(平均时间复杂度为O(1))。这体现了在编程中选择合适数据结构的重要性。
  5. 函数式编程思想:

    • 使用 map() 函数将字符串转换为整数,以及使用 min() 和 max() 函数直接找到最小和最大值,这些都体现了函数式编程中避免副作用、强调函数组合和使用高阶函数的思想。
  6. 抽象和模块化:

    • 代码中的每个部分都有明确的功能,如输入处理、数据存储、结果查找和输出。这种模块化的设计使得代码更易于理解和维护。
  7. 实用主义:

  • 代码的优化是基于实际需求和性能考虑,而不是追求理论上的最优解。这种实用主义的态度在实际编程中非常重要,它确保了代码既高效又易于理解和维护。

通过这些哲学和编程思想的应用,能够编写出既高效又易于理解的代码,这是软件开发中的一个重要目标。


举一反三

基于上述哲学和编程思想,以下是一些实用的技巧和建议,可以帮助在编程中举一反三:

  1. 保持代码简洁:
    • 避免过度设计,只实现当前明确需要的功能。
    • 使用简单的数据结构和算法,除非有明确的性能需求。
    • 编写清晰、直观的代码,避免复杂的控制流和嵌套。
  2. 选择合适的数据结构:
    • 根据操作的类型(如查找、插入、删除)选择最合适的数据结构。
    • 了解不同数据结构的性能特点,如数组、链表、栈、队列、树、图、哈希表等。
    • 在需要快速查找的地方使用哈希表(如Python中的字典)。
  3. 优化时间和空间复杂度:
    • 分析算法的时间和空间复杂度,寻找优化的机会。
    • 避免不必要的计算和数据复制。
    • 使用缓存或记忆化技术来避免重复计算。
  4. 函数式编程技巧:
    • 使用高阶函数(如map、filter、reduce)来处理数据集合。
    • 利用函数式编程的不可变性和纯函数来减少副作用。
    • 使用递归或迭代来处理问题,根据问题的特性选择最合适的方法。
  5. 模块化和抽象:
    • 将代码分解为小的、可重用的模块。
    • 使用抽象来隐藏实现细节,提供清晰的接口。
    • 编写测试来确保模块的正确性和独立性。
  6. 实用主义:
    • 根据实际需求和性能目标来选择解决方案。
    • 不要为了追求理论上的最优解而牺牲代码的可读性和可维护性。
    • 在实际应用中不断测试和调整,以找到最适合的解决方案。
  7. 持续学习和实践:
  • 阅读和分析优秀的代码,学习他人的编程技巧。
  • 参与开源项目,实践和提升编程技能。
  • 定期回顾和重构自己的代码,不断提高代码质量。

通过应用这些技巧和建议,可以在编程中更加灵活和高效,同时也能够提升代码的质量和可维护性。记住,编程是一个不断学习和实践的过程,不断挑战自己,尝试新的方法和技巧,将有助于成为一个更好的程序员。


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

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

相关文章

Redis精要

一、什么是缓存击穿、缓存穿透、缓存雪崩? 缓存穿透 【针对大量非法访问的请求,缓存中没有,直接访问DB】 缓存穿透指的查询缓存和数据库中都不存在的数据,这样每次请求直接打到数据库,就好像缓存不存在 一样。 对于系…

华测监测预警系统2.2 UserEdit.aspx SQL注入致RCE漏洞复现(CVE-2023-5827)

0x01 产品简介 华测监测预警系统2.2是一套针对地质灾害监测预警的科学、完善平台,实现了地质灾害防治管理的科学化、信息化、标准化和可视化。该系统由上海华测导航技术有限公司开发,主要服务于山体滑坡、地裂缝等地质灾害的自动化预警。 0x02 漏洞概述 华测监测预警系统2…

Linux 之内存管理 -free 和 RSS/RES的意义

一、free -h 计算关系: available free buff/cache total used availbleshared 参数 说明 total 总计物理内存的大小 used 已使用的物理内存的大小 free 可用物理内存有多少 shared 多个进程共享的内存总额 buff/cache 写入和读取 磁盘内存缓冲区的大小 avail…

ECharts 雷达图案例001-自定义节点动画

ECharts 雷达图案例001-自定义节点动画 引言 在数据可视化的领域中,ECharts 提供了一种强大的工具来展示多维数据。本文将介绍如何使用 ECharts 创建一个自定义节点样式的雷达图,让数据展示更加生动和个性化。 效果预览 通过自定义节点样式&#xff…

进军韩国5G市场!移远通信5G模组RG500L-EU率先获得KT、LGU+认证

近日,移远通信工规级5G模组RG500L-EU再传喜讯,率先通过了韩国两大运营商KT和LGU的严格认证。​在此之前,该模组已顺利通过KC认证(韩国法规认证),此次再获运营商认证表明,RG500L-EU已完全满足韩国…

服务器权限管理

我们linux服务器上有严格的权限等级,如果权限过高导致误操作会增加服务器的风险。所以对于了解linux系统中的各种权限及要给用户,服务等分配合理的权限十分重要。(权限越大,责任越大) 1.基本权限 U--user用户,G-group…

AI技术+前端的结合(实现图片识别功能)

随着人工智能技术的不断发展,AI在前端设计页面中的应用变得越来越普遍。比如:在电商平台上,可以利用对象检测技术实现商品的自动识别和分类;人脸识别;车辆检测;图片识别等等......其中一个显著的应用是在图…

Python-面向对象编程(超详细易懂)

面向对象编程(oop) 面向对象是Python最重要的特性,在Python中一切数据类型都是面向对象的。 面向对象的编程思想:按照真实世界客观事物的自然规律进行分析,客观世界中存在什么样的实体,构建的软件系统就存在…

Spring自定义标签体系和应用

我们知道&#xff0c;在使用Dubbo框架时&#xff0c;需要指定配置文件中的application、protocol、registry、provider、service等服务器端和客户端的配置项&#xff0c;典型的配置方法如下所示。通过这些配置项&#xff0c;我们可以基于Spring容器来启动Dubbo服务。 <!-- …

Docker Desktop进入界面时一直转圈的解决办法记录

我的win10版本如下&#xff0c;是支持安装的&#xff0c;不支持安装的&#xff0c;可以先升级系统版本&#xff1a; 起初是因为运行Docker Desktop时一直转圈&#xff0c;无法进入主面板&#xff0c;百度之&#xff0c;需要安装hype-v环境&#xff0c;找到以下 勾选Hyper-V下的…

怎么学习PMP才是最正确的?

每个人的学习方式各不相同&#xff0c;不能一概而论说某种学习方式就是错误的。学习方式并没有绝对的对错之分&#xff0c;只能说是否适合自己&#xff0c;是否能够达到预期的学习效果。并不是别人的学习方式就一定适合自己&#xff0c;也不是不适合自己的学习方式就一定是错误…

嵌入式系统基础

嵌入式系统基础主要包括以下几个方面&#xff1a; 1、定义&#xff1a; 嵌入式系统是以应用为中心&#xff0c;以计算机技术为基础&#xff0c;软硬件可裁剪&#xff0c;适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。它由硬件和软件组成&#xff0…

YOLOv8模型代码学习

1.参考文献 链接1 2.网络模型解析 2.1卷积神经单元&#xff08;conv.py&#xff09; 在该文件中定义了yolov8网络中的卷积神经单元&#xff0c;位置如图所示。 def autopad(k, pNone, d1): # kernel(卷积核), padding(填充), dilation(扩张)"""Pad to same…

数据中心技术:大数据时代的机遇与挑战

在大数据时代&#xff0c;数据中心网络对于存储和处理大量信息至关重要。随着云计算的出现&#xff0c;数据中心已成为现代技术的支柱&#xff0c;支持社交媒体、金融服务等众多行业。然而&#xff0c;生成和处理的大量数据带来了一些挑战&#xff0c;需要创新的解决方案。在这…

不同版本的 Rocky Linux 快速更换阿里镜像源

环境&#xff1a;兼容 Rocky Linux 任意版本。 搞服务器系统从 CentOS 折腾到 Rocky Linux&#xff0c;然后又折腾到 Alma Linux&#xff1b;最近因为 RKE2 没有做 Alma Linux 的兼容性&#xff0c;又折腾到了 Rocky Linux &#xff0c;真的是一把鼻涕一把泪呀。但是实在是不理…

深入理解和实现Windows进程间通信(共享内存)

常见的进程间通信方法 常见的进程间通信方法有&#xff1a; 管道&#xff08;Pipe&#xff09;消息队列共享内存信号量套接字 下面&#xff0c;我们将详细介绍共享内存的原理以及具体实现。 什么是共享内存&#xff1f; Windows共享内存&#xff08;Shared Memory in Windo…

【linux】内核源码TCP->IP->L2层函数调用继续摸索中

日志打印的时候&#xff0c;把行数也打印了&#xff1a; 登录 - Gitee.comhttps://gitee.com/r77683962/linux-6.9.0/commit/b847489a9910f68b9581fd8788807c697c82cdbd 上回基于应用层wget操作找到TCP调用的一些接口&#xff0c;并且已经到IP层的一些接口&#xff0c;当前基…

Windows系统Maven下载安装

下载&#xff1a; 官网地址&#xff1a;https://maven.apache.org/download.cgi 安装&#xff1a; 下载下来的是一个压缩包&#xff0c;首先将其解压到你的Maven目标安装位置 接下来为其配置其环境变量 &#xff08;Maven的基础是Java&#xff0c;因此要首先确认已为你的电…

求求你别学了:从 Prompt 到 RAG,从 RAG 到 DSPy

如本瓜在此前的文章中提到过&#xff0c;Prompt 工程已经不中用了&#xff0c;没有人愿意废那么大的劲来学习如何结构化提问&#xff0c;大家想要的就是傻瓜式提问&#xff0c;但是大模型的回答还是精准的、合意的&#xff1b; 后来&#xff0c;大兴 RAG 技术&#xff0c;做专…

Nuxt快速学习开发 - Nuxt3静态资源Assets

Nuxt 使用两个目录来处理样式表、字体或图像等资产。 public/目录内容按原样在服务器根目录中提供。 assets/目录包含您希望构建工具&#xff08;Vite 或 webpack&#xff09;处理的所有资产。 public/目录 public目录用作静态资产的公共服务器&#xff0c;可在您的应用程序定…