每日一题——Python实现PAT乙级1100 校庆(举一反三+思想解读+逐步优化)五千字好文

news2024/7/4 14:20:46


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

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

Python-3.12.0文档解读

目录

我的写法

代码结构和逻辑

时间复杂度分析

空间复杂度分析

总结

我要更强

方法一:直接处理输入,减少重复操作

优化点:

优化后的代码:

时间和空间复杂度分析:

方法二:预处理和一次遍历

优化点:

优化后的代码:

总结:

哲学和编程思想

举一反三


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

我的写法

# 读取输入的整数 N,表示朋友的数量
N = int(input())

# 创建一个空的集合来存储朋友的名字
friends = set()

# 初始化最老朋友的生日为一个较大的日期数值(20190101)
# 初始化最老朋友的名字为空字符串
oldest_friend_birthday = 20190101
oldest_friend = ""

# 循环读取每一个朋友的信息
for i in range(N):
    # 读取朋友的名字(假设包含生日信息)
    friend = input()
    
    # 将朋友添加到集合中
    friends.add(friend)
    
    # 提取朋友的生日信息,假设生日是名字的第6到第14个字符
    tmp = int(friend[6:14])
    
    # 检查当前朋友是否比已知的最老朋友更老
    if tmp < oldest_friend_birthday:
        # 更新最老朋友的生日和名字
        oldest_friend_birthday = tmp
        oldest_friend = friend

# 读取输入的整数 M,表示参与聚会的人数
M = int(input())

# 初始化最老的非朋友的生日为一个较大的日期数值(20190101)
# 初始化最老的非朋友的名字为空字符串
oldest_not_friend_birthday = 20190101
oldest_not_friend = ""

# 初始化出席的朋友的计数器
came_friends_num = 0

# 循环读取每一个出席者的信息
for i in range(M):
    # 读取出席者的名字
    came = input()
    
    # 提取出席者的生日信息,假设生日是名字的第6到第14个字符
    tmp = int(came[6:14])
    
    # 检查出席者是否在朋友集合中
    if came in friends:
        # 如果是朋友,计数器增加
        came_friends_num += 1
    else:
        # 如果不是朋友,检查他们是否比已知的最老非朋友更老
        if tmp < oldest_not_friend_birthday:
            # 更新最老非朋友的生日和名字
            oldest_not_friend = came
            oldest_not_friend_birthday = tmp

# 输出出席的朋友数量
print(came_friends_num)

# 如果有朋友出席,输出最老的朋友,否则输出最老的非朋友
if came_friends_num > 0:
    print(oldest_friend)
else:
    print(oldest_not_friend)

代码结构和逻辑

  1. 输入处理:
    • 代码首先读取校友的数量 N,然后读取每个校友的信息并存储在集合 friends 中。同时,它还会记录最老的校友信息。
    • 接着,代码读取参与校友会的人员数量 M,然后读取每个参与者的信息。对于每个参与者,代码会检查他们是否在 friends 集合中,并记录出席的校友数量。如果不是校友,代码会记录最老的非校友信息。
  2. 输出结果:
  • 最后,代码输出出席的校友数量,以及最老的校友或最老的非校友。

时间复杂度分析

  • 校友信息处理:
    • 读取和处理每个校友的信息需要 O(N) 时间,因为每个校友的信息都需要被读取和处理一次。
    • 查找最老的校友信息在最坏情况下需要遍历所有校友,因此也是 O(N) 时间。
  • 参与校友会人员信息处理:
  • 读取和处理每个参与者的信息需要 O(M) 时间,因为每个参与者的信息都需要被读取和处理一次。
  • 检查每个参与者是否在 friends 集合中需要 O(1) 时间(因为集合的查找操作是常数时间)。
  • 查找最老的非校友信息在最坏情况下需要遍历所有非校友,因此也是 O(M) 时间。

综合来看,整个代码的时间复杂度是 O(N + M)。

空间复杂度分析

  • 校友信息存储:
    • 存储所有校友的信息需要 O(N) 空间,因为每个校友的信息都被存储在集合 friends 中。
  • 参与校友会人员信息存储:
  • 存储最老的校友和最老的非校友信息需要常数空间,即 O(1) 空间。

综合来看,整个代码的空间复杂度是 O(N)。

总结

  • 时间复杂度:O(N + M)
  • 空间复杂度:O(N)

这段代码在时间和空间复杂度上都是高效的,特别是利用集合进行快速查找操作,使得整体性能得到了优化。


我要更强

在这个特定的场景下,优化时间复杂度和空间复杂度的余地并不是很大,因为我们需要处理和检查每个校友和参与者的信息。不过,我们可以考虑一些细微的改进来使代码更简洁和高效。

方法一:直接处理输入,减少重复操作

优化点:
  1. 直接在读取输入时做判断和记录,减少不必要的集合操作。
  2. 尽量合并条件判断逻辑,减少代码分支。

优化后的代码:

# 读取输入的整数 N,表示校友的数量
N = int(input())

# 初始化集合作为校友的集合
friends = set()

# 初始化最老校友的生日和名字
oldest_friend_birthday = 20190101
oldest_friend = ""

# 读取每个校友的信息并处理
for _ in range(N):
    friend = input()
    friends.add(friend)
    birthday = int(friend[6:14])
    if birthday < oldest_friend_birthday:
        oldest_friend_birthday = birthday
        oldest_friend = friend

# 读取输入的整数 M,表示参与校友会的人数
M = int(input())

# 初始化最老非校友的生日和名字
oldest_not_friend_birthday = 20190101
oldest_not_friend = ""

# 出席的校友数量
came_friends_num = 0

# 读取每个出席者的信息并处理
for _ in range(M):
    participant = input()
    birthday = int(participant[6:14])
    if participant in friends:
        came_friends_num += 1
    else:
        if birthday < oldest_not_friend_birthday:
            oldest_not_friend_birthday = birthday
            oldest_not_friend = participant

# 输出出席的校友数量
print(came_friends_num)

# 如果有校友出席,输出最老的校友,否则输出最老的非校友
if came_friends_num > 0:
    print(oldest_friend)
else:
    print(oldest_not_friend)

时间和空间复杂度分析:

  1. 时间复杂度:
    • 处理 N 个校友的信息:O(N)
    • 处理 M 个参与者的信息:O(M)
    • 综合时间复杂度:O(N + M)
  2. 空间复杂度:
  • 存储 N 个校友的信息:O(N)
  • 其他变量消耗的空间为常数级别:O(1)
  • 综合空间复杂度:O(N)

方法二:预处理和一次遍历

优化点:
  1. 在读取校友信息和参与者信息时,尽量减少不必要的变量和集合操作。
  2. 尽量使用单次遍历完成所有处理。

优化后的代码:

# 读取输入的整数 N,表示校友的数量
N = int(input())

# 初始化集合作为校友的集合
friends = set()

# 初始化最老校友的生日和名字
oldest_friend_birthday = 20190101
oldest_friend = ""

# 读取每个校友的信息并处理
for _ in range(N):
    friend = input()
    friends.add(friend)
    birthday = int(friend[6:14])
    if birthday < oldest_friend_birthday:
        oldest_friend_birthday = birthday
        oldest_friend = friend

# 读取输入的整数 M,表示参与校友会的人数
M = int(input())

# 初始化最老非校友的生日和名字
oldest_not_friend_birthday = 20190101
oldest_not_friend = ""

# 出席的校友数量
came_friends_num = 0

# 读取每个出席者的信息并处理
for _ in range(M):
    participant = input()
    birthday = int(participant[6:14])
    if participant in friends:
        came_friends_num += 1
    else:
        if birthday < oldest_not_friend_birthday:
            oldest_not_friend_birthday = birthday
            oldest_not_friend = participant

# 输出出席的校友数量
print(came_friends_num)

# 如果有校友出席,输出最老的校友,否则输出最老的非校友
if came_friends_num > 0:
    print(oldest_friend)
else:
    print(oldest_not_friend)

总结:

尽管在时间和空间复杂度上很难有进一步的优化空间,通过改进代码结构和逻辑,可以使代码更加简洁和高效。上述方法在保持原有复杂度的基础上,优化了代码的可读性和可维护性。


哲学和编程思想

在这些优化方法中,实际上运用了一些重要的编程原则和思想:

  1. DRY(Don't Repeat Yourself):就是避免重复的原则。我们尽量避免在代码中出现重复的或者相似的操作,比如我们在读取输入时就直接完成了一些检查和记录等操作,避免了之后再对这些数据进行额外的处理。
  2. 单一职责原则:这是面向对象编程中的一项基本原则,但也可以应用到函数式编程中。我们在处理每个参与者的信息时,只进行了与该参与者相关的操作(检查是否是校友、更新最老的非校友信息等),避免了将多个任务混在一起,使代码更清晰、更容易理解。
  3. 预先处理:在处理数据或解决问题之前,先进行一些预处理,可以让后续的操作更简单、更快。我们在读取校友信息时,就把他们存储在一个集合中,使得后续判断一个人是否是校友变得非常快速(集合的查找操作平均是 O(1) 时间复杂度)。
  4. 尽早返回:如果已经得到了最终结果,就应该尽早返回,避免进行不必要的操作。我们在找出出席的校友数量后,就可以根据这个数量决定输出最老的校友还是最老的非校友,而不需要再进行其他的检查或判断。
  5. KISS(Keep It Simple, Stupid):简单就是美。我们应该尽可能写出简单、直观、易于理解的代码。这也是我们在优化代码时的一个主要目标。
  6. YAGNI(You Ain't Gonna Need It):你不会需要它的原则。这是敏捷开发中的一项原则,指的是避免过早优化或添加不需要的功能。尽管我们讨论了一些优化方法,但其实在这个特定的场景下,原始的代码已经足够完成任务,无需过度优化。

Code Readability Counts:代码可读性很重要。一个好的代码应该是自解释的,尽可能减少注释的使用。在优化代码时,尽量让代码更简洁、更直观,以提高代码的可读性。


举一反三

  1. 数据结构选择:正确选择合适的数据结构可以极大地提升代码的性能。例如,在这个案例中,我们使用集合(set)来存储校友信息,因为集合的查找时间复杂度是O(1),这对于检查某人是否是校友而言是非常有效的。
  2. 预处理数据:当需要多次使用到某些数据或结果时,可以考虑预处理并存储这些数据或结果,以减少重复计算,提升代码运行效率。在这个案例中,我们预先读取并处理了所有的校友信息。
  3. 合并逻辑:当可能的时候,尝试合并处理逻辑,减少代码分支,这不仅可以提高代码的可读性,还能在一定程度上提高代码的效率。例如,我们在处理参与者信息时,将校友和非校友的处理逻辑合并,避免了额外的条件分支。
  4. 尽早筛选和返回:当代码中有多个可能的输出或结果时,可以通过尽早筛选并返回结果来提高代码的效率。例如,在我们的案例中,我们根据出席的校友数量尽早确定了输出的是最老的校友还是最老的非校友。
  5. 优化代码可读性:良好的代码可读性非常重要,它可以帮助你和其他开发者更容易地理解和维护代码。你可以通过合理的命名、保持函数/方法的单一职责、适当的注释等方式来提高代码的可读性。
  6. 避免过早优化:虽然优化是一个好的实践,但过早地进行优化可能会使代码变得复杂且难以理解。你应该首先确保代码的正确性,然后在必要的时候进行适当的优化。

以上就是基于这个案例和编程原则,可以学习并举一反三的一些技巧。


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

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

相关文章

RK3568驱动指南|第十五篇 I2C-第181章使用GPIO模拟I2C驱动

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

一个能让渲染性能提高100倍的办法

GPU 光线追踪是当今的热门话题&#xff0c;所以让我们来谈谈它&#xff01;今天我们将光线追踪一个单个球体。 使用片段着色器。 是的&#xff0c;我知道。并不特别花哨。你可以在 Shadertoy 上搜索并获得数百个示例(https://www.shadertoy.com/results?querysphere)。甚至已…

速通RK3568开发板多网口网线直连测试

开源鸿蒙硬件方案领跑者 触觉智能 本文适用于在EVB3568开发板上进行多网口网线直连。触觉智能的EVB3568主板基于瑞芯微RK3568处理器&#xff0c;采用22nm先进工艺制程&#xff0c;四核A55 CPU&#xff0c;主频高达2.0GHz&#xff0c;支持高达8GB高速LPDDR4&#xff0c;1T算力N…

Linux miniconda 安装tensorflow-gpu遇到找不到GPU问题

背景&#xff1a; Linux Miniconda python3.9 安装步骤 1、 pip install tensorflow-gpu2.8.0 -i https://pypi.tuna.tsinghua.edu.cn/simple 2、报错如下&#xff1a; 更换镜像源&#xff0c;单独安装 pip install tf-estimator-nightly2.8.0.dev2021122109 -i https:/…

【C语言】typedef 关键字

在C语言中&#xff0c;typedef关键字用于给现有的数据类型起一个新的名字。它在提高代码可读性、简化复杂类型声明、增强可维护性方面非常有用。typedef通常用于定义结构体、指针、函数指针以及其他复杂类型。 基本用法 typedef int MyInt; MyInt x 10;在这个例子中&#xf…

42、nginx之nginx.conf

nginx----web服务器 一、nginx http就是apache&#xff0c;在国内很少。 nginx是开源的&#xff0c;是一款高性能&#xff0c;轻量级的web服务软件。 稳定性高&#xff0c;而且版本迭代比较快&#xff08;修复bug速度比较快&#xff0c;安全性快&#xff09; 消耗系统资源…

中日区块链“大比拼”!中国蚂蚁加大区块链押注资本!日本索尼进军加密货币市场!

科技巨头在区块链和加密货币领域的动作越来越频繁。近期&#xff0c;中国金融科技巨头蚂蚁集团进一步加大了在区块链业务上的投资&#xff0c;而日本电子科技巨头索尼集团则正式进军加密货币交易领域。这些举措反映了两国对于区块链和加密资产领域的不同态度和布局。 蚂蚁集团加…

Load Tensor to local Nvidia GPU

0. 安装Nvidia驱动 ubuntu24.04的安装非常简单&#xff0c;在安装界面&#xff0c;选择为"图形化和其他硬件安装驱动"&#xff0c;重启后即有原版Nvidia驱动(如图Nvidia X xxx) 1.确定电脑上是否有NvidiaGPU且安装好Nvidia驱动 import torch print(torch.version…

LInux SSH Server远程代码执行漏洞 (CVE-2024-6387)处理

一、漏洞描述 2024年7月1日&#xff0c;OpenSSH Server中存在的一个RCE远程代码执行漏洞&#xff08;CVE-2024-6387&#xff0c;又被称为regreSSHion&#xff09;细节被公开&#xff0c;该漏洞影响基于glibc的Linux系统上的OpenSSH Server (sshd)。 默认配置下的OpenSSH Serve…

MIX OTP——依赖项和总体项目

在本章中&#xff0c;我们将讨论如何管理 Mix 中的依赖项。 我们的 kv 应用程序已经完成&#xff0c;现在是时候实现处理我们在第一章中定义的请求的服务器了&#xff1a; 但是&#xff0c;我们不会向 kv 应用程序添加更多代码&#xff0c;而是将 TCP 服务器构建为另一个应用程…

Linux系统之安装Firefox浏览器

Linux系统之安装Firefox浏览器 一、Firefox浏览器介绍1.1 Firefox浏览器介绍1.2 Firefox浏览器特点 二、环境介绍二、本次实践环境介绍2.1 环境规划2.2 本次实践介绍 三、安装firefox浏览器3.1 安装epel3.2 检查yum仓库状态3.3 安装Firefox浏览器3.4 查看Firefox版本 四、在命令…

win11电源设置

把钩子去掉以后 win11的电脑关机才有用 否则&#xff0c;关机了&#xff0c;电脑也实际上一直在运行

partition()方法——分割字符串为元组

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 partition()方法根据指定的分隔符将字符串进行分割。如果字符串中包含指定的分隔符&#xff0c;则返回一个3元的元组&#xff0c;第一个为…

HarmonyOS(38) UIAbility里icon和label的作用

UIAbility里icon和label的作用 icon和label实际效果测试代码传送门参考资料 icon和label 为使应用能够正常使用UIAbility&#xff0c;需要在module.json5配置文件的abilities标签中声明UIAbility的名称、入口、标签等相关信息&#xff1a; {"module": {..."ab…

3.3prometheus命令行参数讲解

本节重点介绍 : target页面flags页面status页面tsdb-status页面 访问地址 $ip:9090 target页面 flags页面 展示命令行参数的&#xff0c;没设置的取默认值 status页面 描述运行信息和编译的信息 tsdb-status页面 打印存储的运行状态信息帮我们定位重查询的 服务发现页面…

怎么把录音转文字?推荐几个简单易操作的方法

在小暑这个节气里&#xff0c;炎热的天气让人分外渴望效率up&#xff01;Up&#xff01;Up&#xff01; 对于那些在会议或课堂中急需记录信息的朋友们&#xff0c;手写笔记的速度往往难以跟上讲话的节奏。此时&#xff0c;电脑录音转文字软件就像一阵及时雨&#xff0c;让记录…

深度学习原理与Pytorch实战

深度学习原理与Pytorch实战 第2版 强化学习人工智能神经网络书籍 python动手学深度学习框架书 TransformerBERT图神经网络&#xff1a; 技术讲解 编辑推荐 1.基于PyTorch新版本&#xff0c;涵盖深度学习基础知识和前沿技术&#xff0c;由浅入深&#xff0c;通俗易懂&#xf…

动态顺序表实现通讯录

系列文章目录 【数据结构】顺序表 文章目录 系列文章目录前言一、通讯录的功能要求二、通讯录的代码实现1. 新建文件2. 创建通讯录的结构体3. 对顺序表文件进行修改4. 通讯录具体功能实现4.1. 通讯录的初始化和销毁4.2. 增加联系人信息&#xff08;尾插&#xff09;4.3. 查找指…

无污染的独立海域-第13届蓝桥杯省赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第90讲。 无污染的独立海域…

余承东在母校西工大毕业典礼演讲:定位决定地位,眼界决定境界。

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 【6月29日&#xff0c;西北工业大学2024届本科生毕业典礼暨学位授予仪式隆重举行。典礼上&#xff0c;华为常务董事、终端BG 董事长、智能汽车解决方案BU 董事长余承东作为校友代表致辞&#xff0c;为毕业生…