每日一题——Python代码实现PAT甲级1006 Sign In and Sign Out(举一反三+思想解读+逐步优化)五千字好文


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

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

Python-3.12.0文档解读

目录

我的写法

代码点评

时间复杂度分析

空间复杂度分析

我要更强

优化建议

优化后的代码

时间复杂度和空间复杂度分析

优化说明

哲学和编程思想

抽象化(Abstraction):

模块化(Modularity):

效率优化(Efficiency Optimization):

数据驱动(Data-Driven):

迭代与增量开发(Iterative and Incremental Development):

算法和数据结构的选择(Algorithm and Data Structure Selection):

KISS原则(Keep It Simple, Stupid):

DRY原则(Don't Repeat Yourself):

单一职责原则(Single Responsibility Principle):

测试驱动开发(Test-Driven Development):

举一反三


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

我的写法

# 读取输入的M,表示接下来会有M行输入数据
M = int(input())

# 初始化变量,用于记录解锁和锁定的人以及对应的时间
who_unlocked = ''
who_locked = ''
time_unlocked = 235959  # 初始化为最大可能的时间(23:59:59)
time_locked = 0  # 初始化为最小可能的时间(00:00:00)

# 循环M次,每次处理一行输入数据
for i in range(M):
    # 读取一行输入,分割成三个部分:id_num(人员编号),in_time(进入时间),out_time(离开时间)
    id_num, in_time, out_time = input().split()
    
    # 将时间字符串转换为整数,去掉冒号,方便比较
    in_time = int(in_time.replace(':', ''))
    out_time = int(out_time.replace(':', ''))
    
    # 如果当前记录的进入时间早于已知的最早进入时间,则更新最早进入时间和对应的人员编号
    if in_time < time_unlocked:
        time_unlocked = in_time
        who_unlocked = id_num
    
    # 如果当前记录的离开时间晚于已知的最晚离开时间,则更新最晚离开时间和对应的人员编号
    if time_locked < out_time:
        time_locked = out_time
        who_locked = id_num

# 输出最早进入和最晚离开的人员编号
print(f"{who_unlocked} {who_locked}")

代码点评

这段代码实现了从用户输入中读取一系列人员的进出记录,并找出最早进入和最晚离开的人员编号。以下是对代码的专业点评:

  1. 输入处理:代码通过input()函数读取用户输入,并使用split()方法分割输入数据,这使得代码具有良好的交互性和灵活性。
  2. 时间处理:将时间字符串转换为整数,以便于比较。这种转换简化了时间比较的逻辑,但需要注意时间格式的统一性,确保所有时间都能正确转换。
  3. 逻辑清晰:代码通过两个变量time_unlocked和time_locked分别记录最早进入和最晚离开的时间,逻辑清晰,易于理解。
  4. 变量初始化:time_unlocked初始化为最大可能的时间,time_locked初始化为最小可能的时间,这是合理的初始化策略,确保在第一次比较时能够正确更新。
  5. 输出格式:使用格式化字符串f"{who_unlocked} {who_locked}"输出结果,简洁明了。

时间复杂度分析

  • 读取输入:每次读取一行输入,时间复杂度为O(M),其中M是输入的行数。
  • 字符串处理:每次处理一行输入中的时间字符串,时间复杂度为O(1),因为每次操作都是固定的。
  • 循环:外层循环执行M次,每次循环内部的时间复杂度为O(1),因此总的时间复杂度为O(M)。

综上,这段代码的时间复杂度为O(M)。

空间复杂度分析

  • 存储输入:每次循环中,存储三个变量(id_num, in_time, out_time),空间复杂度为O(1)。
  • 存储结果:存储两个时间变量和两个人员编号变量,空间复杂度为O(1)。

由于空间复杂度不随输入规模M的增加而增加,因此这段代码的空间复杂度为O(1)。

总结,这段代码在时间和空间效率上都表现良好,逻辑清晰,适合处理此类问题。


我要更强

优化建议

  1. 输入优化:可以一次性读取所有输入,然后进行处理,这样可以减少每次读取输入的开销。
  2. 时间处理优化:可以使用更高效的数据结构(如字典)来存储人员和时间的关系,这样可以快速查找和更新。
  3. 逻辑优化:可以合并判断条件,减少不必要的比较。

优化后的代码

# 一次性读取所有输入,并分割成列表
all_inputs = [input().split() for _ in range(int(input()))]

# 初始化字典,用于存储每个人员的最早进入时间和最晚离开时间
person_times = {}

# 处理输入数据
for id_num, in_time_str, out_time_str in all_inputs:
    # 将时间字符串转换为整数
    in_time = int(in_time_str.replace(':', ''))
    out_time = int(out_time_str.replace(':', ''))
    
    # 如果人员编号不在字典中,初始化其时间记录
    if id_num not in person_times:
        person_times[id_num] = {'in_time': in_time, 'out_time': out_time}
    else:
        # 更新最早进入时间和最晚离开时间
        person_times[id_num]['in_time'] = min(person_times[id_num]['in_time'], in_time)
        person_times[id_num]['out_time'] = max(person_times[id_num]['out_time'], out_time)

# 找出最早进入和最晚离开的人员编号
earliest_in = min(person_times, key=lambda x: person_times[x]['in_time'])
latest_out = max(person_times, key=lambda x: person_times[x]['out_time'])

# 输出结果
print(f"{earliest_in} {latest_out}")

时间复杂度和空间复杂度分析

  • 时间复杂度:读取所有输入的时间复杂度为O(M),处理输入的时间复杂度为O(M),查找最早进入和最晚离开的时间复杂度为O(M)。因此,总的时间复杂度为O(M)。
  • 空间复杂度:存储所有人员的时间记录,空间复杂度为O(M),其中M是输入的行数。

优化说明

  1. 输入优化:通过列表推导一次性读取所有输入,减少了多次调用input()的开销。
  2. 时间处理优化:使用字典存储每个人员的最早进入时间和最晚离开时间,可以快速查找和更新。
  3. 逻辑优化:通过字典的键值对存储,简化了更新逻辑,减少了不必要的比较。

这种优化方法在处理大量数据时更为高效,特别是在输入数据量较大时,能够显著提升性能。


哲学和编程思想

优化代码的过程中融入了多种哲学和编程思想,以下是一些主要的思想:

  1. 抽象化(Abstraction):

    • 通过使用字典来存储人员和时间的关系,抽象化了数据的存储和访问方式,使得代码更加简洁和易于理解。
  2. 模块化(Modularity):

    • 代码中的每个功能(如输入处理、时间转换、结果输出)都被模块化为独立的步骤,这有助于代码的维护和测试。
  3. 效率优化(Efficiency Optimization):

    • 通过一次性读取所有输入和使用字典来存储数据,减少了重复的输入操作和提高了数据访问的速度,体现了对程序运行效率的追求。
  4. 数据驱动(Data-Driven):

    • 代码的逻辑主要围绕数据处理展开,通过分析和操作数据来解决问题,这是数据驱动编程的体现。
  5. 迭代与增量开发(Iterative and Incremental Development):

    • 优化过程可以看作是一个迭代和增量的过程,每次优化都基于前一次的结果,逐步改进代码的性能和可读性。
  6. 算法和数据结构的选择(Algorithm and Data Structure Selection):

    • 选择合适的数据结构(如字典)来存储和操作数据,这是算法设计中的关键步骤,直接影响程序的效率。
  7. KISS原则(Keep It Simple, Stupid):

    • 代码优化过程中尽量保持简单,避免过度复杂化,这有助于提高代码的可读性和可维护性。
  8. DRY原则(Don't Repeat Yourself):

    • 通过抽象和模块化,避免了代码的重复,这是DRY原则的体现,有助于减少错误和提高代码质量。
  9. 单一职责原则(Single Responsibility Principle):

    • 每个函数或模块只负责一个功能,这有助于保持代码的清晰和易于维护。
  10. 测试驱动开发(Test-Driven Development):

  • 虽然代码中没有直接体现,但在实际开发中,优化后的代码应该通过测试来验证其正确性和性能,这是测试驱动开发的思想。

这些哲学和编程思想在优化代码的过程中相互交织,共同指导着代码的改进和优化。通过应用这些思想,可以提高代码的质量、效率和可维护性。


举一反三

掌握这些哲学和编程思想后,可以将它们应用到更广泛的编程场景中,以下是一些技巧和建议,帮助举一反三:

  1. 抽象化与模块化:
    • 在设计程序时,尝试将复杂的问题分解为更小的、可管理的部分。每个部分应该负责一个明确的功能,并且可以独立测试和维护。
    • 使用类和对象来封装数据和操作,这样可以提高代码的可重用性和可维护性。
  2. 效率优化:
    • 分析代码中的瓶颈,通常是循环和数据处理部分。优化这些部分可以显著提高整体性能。
    • 使用合适的数据结构和算法来解决问题。例如,如果需要频繁查找,使用哈希表(如Python中的字典)通常比列表更高效。
  3. 数据驱动:
    • 当面对需要处理大量数据的问题时,考虑数据的特点和结构,设计适合的数据模型和处理流程。
    • 使用数据库或数据存储服务来管理数据,这样可以更有效地处理和查询数据。
  4. 迭代与增量开发:
    • 采用敏捷开发方法,将项目分解为多个小迭代,每个迭代都包含设计、编码、测试和反馈。
    • 在每个迭代中,专注于实现最重要的功能,然后逐步添加更多功能。
  5. 算法和数据结构的选择:
    • 学习和理解不同的算法和数据结构,了解它们的时间和空间复杂度,以及适用场景。
    • 在解决问题时,首先考虑是否存在已知的算法或数据结构可以应用。
  6. KISS原则:
    • 编写代码时,尽量保持简单明了,避免过度设计。
    • 使用清晰的命名和注释,确保代码易于理解和维护。
  7. DRY原则:
    • 避免在代码中重复相同的逻辑。如果发现重复,考虑将其抽象为一个函数或模块。
    • 使用配置文件或环境变量来管理重复的设置,而不是在代码中硬编码。
  8. 单一职责原则:
    • 确保每个函数、类或模块只做一件事,并且做好这件事。
    • 当一个组件变得过于复杂时,考虑将其分解为更小的组件。
  9. 测试驱动开发:
  • 在编写代码之前,先编写测试用例。这有助于确保代码的正确性,并且可以作为文档来指导代码的实现。
  • 定期运行测试,确保代码的稳定性和可靠性。

通过将这些哲学和编程思想应用到实际的编程实践中,可以提高代码的质量,减少错误,并且更有效地解决问题。记住,编程不仅仅是写代码,更是一种思维方式和解决问题的艺术。

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

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

相关文章

ONLYOFFICE 8.1:全面升级,PDF编辑与本地化加强版

目录 &#x1f4d8; 前言 &#x1f4df; 一、什么是 ONLYOFFICE 桌面编辑器&#xff1f; &#x1f4df; 二、ONLYOFFICE 8.1版本新增了那些特别的实用模块&#xff1f; 2.1. 轻松编辑器 PDF 文件 2.2. 用幻灯片版式快速修改幻灯片 2.3. 无缝切换文档编辑、审阅和查…

【教程】安装DGL环境

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 关于cuda的安装&#xff0c;可以看这个&#xff1a; 【教程】保姆级安装NVIDIA CUDA、CUDNN环境全纪录解决SSH一段时间自动断开报Destination Host Un…

小型数据中心是什么?如何建设?

在数字化时代&#xff0c;小型数据中心正成为许多企业和组织加强数据管理和服务扩展的理想选择。与传统大型数据中心相比&#xff0c;小型数据中心以其灵活性、高效性和相对较低的运营成本吸引着越来越多的关注。然而&#xff0c;要成功建设一个小型数据中心&#xff0c;并确保…

2024年数据、自动化与智能计算国际学术会议(ICDAIC 2024)

全称&#xff1a;2024年数据、自动化与智能计算国际学术会议&#xff08;ICDAIC 2024&#xff09; 会议网址:http://www.icdaic.com 会议地点: 厦门 投稿邮箱&#xff1a;icdaicsub-conf.com投稿标题&#xff1a;ArticleTEL。投稿时请在邮件正文备注&#xff1a;学生投稿&#…

测评:【ONLYOFFICE】版本更迭与AI加持下的最新ONLYOFFICE桌面编辑器8.1

你是否还在为没有一款合适的在线桌面编辑器而苦恼&#xff1f;你是否还在因为办公软件的选择过少而只能使用WPS或者office&#xff1f;随着办公需求的不断变化和发展&#xff0c;办公软件也在不断更新和改进。ONLYOFFICE 作为一款全功能办公软件&#xff0c;一直致力于为用户提…

android-aidl4

转&#xff1a;Android Aidl的使用_android aidl使用-CSDN博客 一.准备 Parcelable&#xff0c;可以理解成只是把car整个对象在aidl中进行传递&#xff0c;就理解成一个car的一个类吧&#xff0c;和其他类使用一样就行了&#xff0c;回调&#xff1a;把接口作为参数放在函数参…

场外期权交易流程以及参与方式是什么?

今天带你了解场外期权交易流程以及参与方式是什么&#xff1f;场外期权&#xff0c;是非标准化的期权合约&#xff0c;由买卖双方私下协商达成&#xff0c;灵活性较高。由于这种合约的条款可以根据双方的具体需求进行定制&#xff0c;因此它提供了比交易所交易的标准化期权更多…

多功能推拉力测试机可实现焊球推力测试

LB-8100A 多功能推拉力测试机广泛应于与 LED 封装测试、IC 半导体封 装测试、TO 封装测试、IGBT 功率模块封装测试、光电子元器件封装测试、汽 车领域、航天航空领域、军工产品测试、研究机构的测试及各类院校的测试 研究等应用。 多功能推拉力测试机设置主要结构&#xff1a;…

医疗器械3D全景展会在线漫游创造数字化时代的展览新篇章

在数字化浪潮的引领下&#xff0c;VR虚拟网上展会正逐渐成为企业展示品牌实力、吸引潜在客户的首选平台。我们与广交会携手走过三年多的时光&#xff0c;凭借优质的服务和丰富的经验&#xff0c;赢得了客户的广泛赞誉。 面对传统展会活动繁多、企业运营繁忙的挑战&#xff0c;许…

【MySQL】数据类型和表的约束

1. 数据类型 分类数据类型解释数值类型BIT (M)位类型。M位数&#xff0c;默认为1范围1-64BOOL01表示真假TINYINT [UNSIGNED]8位整型SMALLINT [UNDIGNED]16位短整型INT [UNSIGNED]32位整型BIGINT [UNSIGNED]64位长整型小数类型FLOAT [ (M, D) ] [UNSIGNED]32位浮点类型&#xf…

【机器学习】机器学习重要方法——深度学习:理论、算法与实践

文章目录 引言第一章 深度学习的基本概念1.1 什么是深度学习1.2 深度学习的历史发展1.3 深度学习的关键组成部分 第二章 深度学习的核心算法2.1 反向传播算法2.2 卷积神经网络&#xff08;CNN&#xff09;2.3 循环神经网络&#xff08;RNN&#xff09; 第三章 深度学习的应用实…

群晖NAS部署VoceChat私人聊天系统并一键发布公网分享好友访问

文章目录 前言1. 拉取Vocechat2. 运行Vocechat3. 本地局域网访问4. 群晖安装Cpolar5. 配置公网地址6. 公网访问小结 7. 固定公网地址 前言 本文主要介绍如何在本地群晖NAS搭建一个自己的聊天服务Vocechat&#xff0c;并结合内网穿透工具实现使用任意浏览器远程访问进行智能聊天…

android adb常用命令集

1、系统调试 #adb shell&#xff1a;进入设备的 shell 命令行界面&#xff0c;可以在此执行各种 Linux 命令和特定的 Android 命令。 #adb shell dumpsys&#xff1a;提供关于系统服务和其状态的详细信息。 #adb logcat&#xff1a;实时查看设备的日志信息。可以使用过滤条件来…

浅析Vite本地构建原理

前言 随着Vue3的逐渐普及以及Vite的逐渐成熟&#xff0c;我们有必要来了解一下关于vite的本地构建原理。 对于webpack打包的核心流程是通过分析JS文件中引用关系&#xff0c;通过递归得到整个项目的依赖关系&#xff0c;并且对于非JS类型的资源&#xff0c;通过调用对应的loade…

使用 Reqable 在 MuMu 模拟器进行App抓包(https)

1、为什么要抓包&#xff1f; 用开发手机应用时&#xff0c;查看接口数据不能像在浏览器中可以直接通过network查看&#xff0c;只能借助抓包工具来抓包&#xff0c;还有一些线上应用我们也只能通过抓包来排查具体的问题。 2、抓包工具 实现抓包&#xff0c;需要一个抓包工具…

Java8使用Stream流实现List列表查询、统计、排序、分组、合并

Java8使用Stream流实现List列表查询、统计、排序以及分组 目录 一、查询方法1.1 forEach1.2 filter(T -> boolean)1.3 filterAny() 和 filterFirst()1.4 map(T -> R) 和 flatMap(T -> Stream)1.5 distinct()1.6 limit(long n) 和 skip(long n) 二、判断方法2.1 anyMa…

G7 - Semi-Supervised GAN 理论与实战

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目录 理论知识模型实现引用、配置参数初始化权重定义算法模型模型配置模型训练训练模型 模型效果总结与心得体会 理论知识 在条件GAN中&#xff0c;判别器只用…

轻松搞定数据可视化配色,这份指南助你一臂之力!

配色是数据可视化图表的主要因素。一组合适的配色可以表达数据的重点和趋势&#xff0c;而不良的配色会削弱可视化表达的有效性。在本文中&#xff0c;我将梳理数据可视化中使用的配色板类型&#xff0c;通过案例揭示数据可视化配色技巧&#xff0c;并介绍可生成配色板的插件&a…

Day 32:503. 下一个更大的元素Ⅱ

Leetcode 503. 下一个更大的元素Ⅱ 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序&#xff0c;这个数字之后的第一个比它…

嵌入式实验---实验七 SPI通信实验

一、实验目的 1、掌握STM32F103SPI通信程序设计流程&#xff1b; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、使用STM32F103R6通过74HC595控制一位LID数码管&#xff0c;实现以下两个要求&#xff1a; &#xff08;1&#xff09;数码管从0到9循环显示&#xff1b; …