每日一题——Python实现PAT乙级1018 锤子剪刀布(举一反三+思想解读+逐步优化)五千字好文


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

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

Python-3.12.0文档解读

目录

我的写法

代码结构与逻辑

时间复杂度分析

空间复杂度分析

代码优化建议

总结

我要更强

优化方法

优化后的代码

代码注释

时间复杂度和空间复杂度

哲学和编程思想

举一反三


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

我的写法

N=int(input())
jia_wins_counts={'B':0,'C':0,'J':0}
yi_wins_counts={'B':0,'C':0,'J':0}
jia_results_counts={1:0,0:0,-1:0}# 赢,平,输

def jia_result(jia,yi):
    if jia==yi:
        return 0
    if (jia=='J' and yi=='B') or (jia=='B' and yi=='C') or (jia=='C' and yi=='J'):
        return 1
    return -1

for i in range(N):
    jia,yi=input().split()
    cur_jia_result=jia_result(jia,yi)
    jia_results_counts[cur_jia_result]+=1
    if cur_jia_result==1:
        jia_wins_counts[jia]+=1
    elif cur_jia_result==-1:
        yi_wins_counts[yi]+=1

print(*jia_results_counts.values())
print(*list(jia_results_counts.values())[::-1])
print(sorted(jia_wins_counts.items(),key=lambda x:(-x[1],x[0]))[0][0],end=' ')
print(sorted(yi_wins_counts.items(),key=lambda x:(-x[1],x[0]))[0][0])

 

这段代码实现了一个简单的石头剪刀布游戏结果统计程序。它读取多场比赛的结果,统计甲和乙的胜负情况,并输出各自获胜次数最多的手势。以下是对这段代码的专业点评:

代码结构与逻辑

  1. 输入处理:代码首先读取比赛次数 N,然后通过循环读取每场比赛的结果,并对结果进行处理和统计。
  2. 结果判断:通过定义的 jia_result 函数来判断甲的比赛结果(赢、平、输)。
  3. 统计更新:根据比赛结果更新甲和乙的获胜次数统计字典以及甲的比赛结果统计字典。
  4. 输出结果:最后输出甲的胜负平次数、乙的胜负平次数(顺序相反),以及甲和乙各自获胜次数最多的手势。

时间复杂度分析

  • 输入读取:读取 N 场比赛的结果,时间复杂度为 O(N)。
  • 结果判断:每次比赛的结果判断是常数时间操作,时间复杂度为 O(1)。
  • 统计更新:每次比赛的统计更新也是常数时间操作,时间复杂度为 O(1)。
  • 排序输出:最后对甲和乙的获胜次数进行排序,排序的时间复杂度为 O(3 log 3),即 O(1),因为每次排序的元素数量是固定的(B、C、J 三种手势)。

综合来看,整个程序的时间复杂度为 O(N),其中 N 是比赛次数。

空间复杂度分析

  • 输入存储:存储比赛次数 N,空间复杂度为 O(1)。
  • 统计字典:存储甲和乙的获胜次数统计字典以及甲的比赛结果统计字典,每个字典的大小是固定的(3 个元素),空间复杂度为 O(1)。
  • 临时变量:在循环中使用的临时变量(如 jia 和 yi),空间复杂度为 O(1)。

综合来看,整个程序的空间复杂度为 O(1),即常数空间复杂度。

代码优化建议

  1. 输入输出优化:可以使用 sys.stdin 和 sys.stdout 进行输入输出优化,特别是在处理大量数据时。
  2. 代码复用:可以将甲和乙的统计逻辑进行抽象,减少重复代码。
  3. 异常处理:增加对输入数据的异常处理,确保程序的健壮性。

总结

这段代码结构清晰,逻辑简单,时间复杂度和空间复杂度均为 O(N) 和 O(1),在处理合理范围内的数据时性能良好。通过一些优化,可以进一步提升代码的效率和可读性。


我要更强

优化时间复杂度和空间复杂度的方法通常涉及减少不必要的计算和存储。对于这段代码,主要的优化点在于减少重复计算和简化数据结构。以下是一些可能的优化方法,并附上优化后的完整代码和注释:

优化方法

  1. 减少重复计算:在结果判断函数中,可以预先定义一个胜负关系表,避免每次都进行条件判断。
  2. 简化数据结构:使用数组代替字典来存储获胜次数,因为手势种类是固定的。
  3. 输入输出优化:使用 sys.stdin 和 sys.stdout 进行输入输出优化。

优化后的代码

import sys

# 读取输入的比赛次数
N = int(input())

# 定义胜负关系表
win_table = {
    'B': 'C',
    'C': 'J',
    'J': 'B'
}

# 初始化甲和乙的获胜次数统计数组
jia_wins_counts = [0, 0, 0]  # B, C, J
yi_wins_counts = [0, 0, 0]   # B, C, J

# 甲的比赛结果统计数组,分别记录赢、平、输的次数
jia_results_counts = [0, 0, 0]  # 赢,平,输

# 循环读取每一场比赛的结果
for i in range(N):
    jia, yi = input().split()
    if jia == yi:
        jia_results_counts[1] += 1  # 平局
    elif win_table[jia] == yi:
        jia_results_counts[0] += 1  # 甲赢
        if jia == 'B':
            jia_wins_counts[0] += 1
        elif jia == 'C':
            jia_wins_counts[1] += 1
        else:
            jia_wins_counts[2] += 1
    else:
        jia_results_counts[2] += 1  # 甲输
        if yi == 'B':
            yi_wins_counts[0] += 1
        elif yi == 'C':
            yi_wins_counts[1] += 1
        else:
            yi_wins_counts[2] += 1

# 输出甲的赢、平、输次数
print(*jia_results_counts)

# 输出乙的赢、平、输次数(顺序与甲相反)
print(*jia_results_counts[::-1])

# 输出甲和乙各自获胜次数最多的手势
jia_max_index = max(range(3), key=lambda i: jia_wins_counts[i])
yi_max_index = max(range(3), key=lambda i: yi_wins_counts[i])
print('BCJ'[jia_max_index], end=' ')
print('BCJ'[yi_max_index])

代码注释

  1. 胜负关系表:通过预定义的胜负关系表 win_table,避免了每次比赛结果判断时的条件判断。
  2. 数组统计:使用数组 jia_wins_counts 和 yi_wins_counts 来存储获胜次数,简化了数据结构。
  3. 结果输出:通过 max 函数和索引直接找到获胜次数最多的手势,简化了输出逻辑。

时间复杂度和空间复杂度

  • 时间复杂度:仍然是 O(N),但由于减少了条件判断,实际运行效率会有所提升。
  • 空间复杂度:仍然是 O(1),但由于使用了数组代替字典,空间占用更少。

通过这些优化,代码的执行效率和空间利用率都得到了提升。


哲学和编程思想

这些优化方法体现了几个重要的哲学和编程思想:

  1. 抽象与封装:通过定义胜负关系表 win_table,将游戏规则抽象为一个数据结构,封装了具体的胜负逻辑,使得代码更加模块化和易于理解。这种抽象减少了代码的复杂性,提高了代码的可维护性。
  2. 数据驱动设计:使用数组来存储获胜次数,而不是字典,这是一种数据驱动的设计思想。数组的使用简化了数据结构,减少了内存占用,同时也简化了代码逻辑,使得数据处理更加高效。
  3. 避免重复:通过预先定义胜负关系表,避免了在每次循环中重复进行条件判断,这是“避免重复”(DRY - Don't Repeat Yourself)原则的体现。这个原则强调在软件开发中减少重复代码,提高代码的复用性和可维护性。
  4. 优化输入输出:虽然在这个例子中没有使用 sys.stdin 和 sys.stdout,但这是一个常见的优化输入输出的方法。这种优化体现了“性能优化”的思想,特别是在处理大量数据时,优化输入输出可以显著提高程序的运行效率。
  5. 简单性原则:整个优化过程追求代码的简单性,即“保持简单”(KISS - Keep It Simple, Stupid)原则。这个原则强调在设计和编写代码时,应该尽可能保持代码的简单性,避免不必要的复杂性。
  6. 关注点分离:代码的不同部分(输入处理、结果判断、统计更新、结果输出)被清晰地分离,每个部分只关注自己的任务。这是“关注点分离”(Separation of Concerns)原则的体现,它有助于提高代码的可读性和可维护性。
  7. 效率优先:在优化过程中,考虑了时间复杂度和空间复杂度,体现了“效率优先”的思想。在软件开发中,效率是一个重要的考虑因素,特别是在处理大量数据或对性能有严格要求的场景中。

通过这些哲学和编程思想的运用,代码不仅变得更加高效和简洁,而且也更容易理解和维护。这些原则和思想是软件工程中的基础,对于任何软件开发者来说都是非常有价值的。


举一反三

根据上述哲学和编程思想以及本题目的情况,以下是一些具体的技巧和建议,可以帮助在其他编程任务中举一反三:

  1. 抽象化规则:在本题目中,游戏规则被抽象为一个胜负关系表。在其他问题中,如果存在类似的规则或逻辑,也可以尝试将其抽象化,以便于代码的复用和维护。
  2. 选择合适的数据结构:在本题目中,使用数组来存储获胜次数,而不是字典。在其他问题中,根据数据的特点和操作需求,选择最合适的数据结构可以提高代码的效率。
  3. 避免重复计算:在本题目中,通过预定义胜负关系表避免了重复的条件判断。在其他问题中,如果发现有重复的计算或逻辑,可以考虑使用缓存或预计算来优化。
  4. 关注性能瓶颈:在本题目中,优化了时间复杂度和空间复杂度。在其他问题中,通过分析代码的性能瓶颈,可以有针对性地进行优化。
  5. 保持代码简单:在本题目中,追求代码的简单性。在其他问题中,避免过度设计,保持代码的简洁和清晰,可以提高代码的可读性和可维护性。
  6. 模块化设计:在本题目中,代码的不同部分被清晰地分离。在其他问题中,将代码分解成独立的模块,每个模块负责一个清晰的功能,可以提高代码的组织性和可扩展性。
  7. 考虑输入输出优化:在本题目中,虽然没有直接涉及,但在处理大量数据时,优化输入输出操作可以显著提高程序的运行效率。
  8. 学习和应用设计模式:在其他问题中,学习和应用常见的设计模式,如单例模式、工厂模式、观察者模式等,可以帮助你更好地解决特定类型的问题。
  9. 编写可测试的代码:在其他问题中,编写易于测试的代码,可以提高代码的质量,并帮助你更快地发现和修复问题。
  10. 持续学习和实践:软件开发是一个不断发展的领域,持续学习新的编程思想、技术和工具,并将它们应用到实践中,可以帮助你不断提高编程技能。

通过将这些技巧和建议应用到编程实践中,将能够更好地理解和解决各种编程问题,提高代码的质量和效率,并在未来的项目中更加灵活和高效地工作。


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

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

相关文章

【java计算机毕设】美容院管理系统 项目源代码MySQL springboot vue html maven+文档 前后端可分离也可不分离

目录 1项目功能 2项目介绍 3项目地址 1项目功能 【java计算机毕设】美容院管理系统 项目源代码MySQL springboot vue html maven文档 前后端可分离也可不分离 2项目介绍 系统功能: 美容院管理系统包括管理员、用户俩种角色。 管理员功能包括个人中心模块用于修改…

“论单元测试方法及应用”精选范文,软考高级论文,系统架构设计师论文

论文真题 1、概要叙述你参与管理和开发的软件项目,以吸你所担的主要工作。 2、结给你参与管理和开发的软件项目,简要叙述单元测试中静态测试和动态测试方法的基本内容。 3、结给你惨与管理和研发的软件项目,体阐述在玩测试过程中,如何确定白盒测试的覆盖标准,及如…

【C语言】sizeof 关键字

在C语言中,sizeof运算符用于计算数据类型或变量的大小(以字节为单位)。sizeof是一个编译时运算符,它在编译阶段确定类型或变量的大小,而不是在运行时。 基本用法 sizeof可以用于计算基本数据类型、数组、结构体以及指…

银湖资本与UIBE达成战略合作,共同推动股权投资领域发展

近日,全球知名私募股权投资公司银湖资本(Silver Lake Partners)宣布与对外经济贸易大学(UIBE)校友发起的“UIBE阿波罗股权投资俱乐部”达成战略合作协议。此举不仅标志着双方在股权投资领域的深度合作,也为…

LVS-DR负载均衡

LVS-DR负载均衡 LVS—DR工作模式 原理 客户端访问调度器的VIP地址,在路由器上应该设置VIP跟调度器的一对一的映射关系,调度器根据调度算法将该请求“调度“到后端真实服务器,真实服务器处理完毕后直接将处理后的应答报文发送给路由器&#xf…

使用 draw.io 画图

尽管我非常喜欢 wps 和 office 的 ppt 画图,但因为它们对数学公式的糟糕支持,我不得不另外寻找一个画图工具。当然我也同样很喜欢 visio ,但同样的,它对数学公式的支持糟糕,另外,最为重要的是,v…

不同的llm推理框架

vLLM适用于大批量Prompt输入,并对推理速度要求比较高的场景。 实际应用场景中,TensorRT-LLM通常与Triton Inference Server结合起来使用,NVIDIA官方能够提供更适合NVIDIA GPU运行的高效Kernel。 LightLLM比较轻量、易于扩展、易于上手&…

Android 抓取 CPU 资源信息

在 Android 开发中,使用 ADB(Android Debug Bridge)命令获取 CPU 资源信息有很多重要的作用。这些命令可以帮助开发者在多种情况下分析和优化应用性能、解决问题以及进行系统性调试。 以下列举一些 ABD 获取 CPU 资源信息的命令 获取 CPU 核…

农作物生长环境的远程监控与智能调控

农作物生长环境的远程监控与智能调控 农作物生长环境的远程监控与智能调控技术,作为现代农业科技的核心组成部分,正逐步革新传统农业的生产模式,推动农业向精准化、智能化转型。这一技术体系综合应用了物联网、大数据、云计算以及人工智能等…

C语言实战 | Flappy Bird游戏

Flappy Bird游戏是由一名越南游戏制作者独自开发的,曾经风靡全球。游戏规则非常简单,玩家必须控制一只小鸟,跨越由各种长度的水管所组成的障碍物,如果撞上管道游戏就结束,如图11.11所示。 ■ 图11.11Flappy Bird 游戏 …

启明智显Model3A芯片方案7寸高清触摸屏ZX7D00CM21S:开箱、设置与实操全攻略指南

一、背景 本指南将详细介绍启明智显的Model3A芯片方案下的7寸高清触摸屏ZX7D00CM21S的开箱步骤、基础设置以及实操应用。无论您是电子爱好者、开发者还是工程师,这份指南都能助您快速上手并充分利用这款触摸屏的各项功能。 二、硬件介绍 ZX7D00CM21S 7寸高清触摸屏是…

不知几DAY的Symfony---RCE复现

感谢红队大佬老流氓的供稿,此篇文章是针对Symfony框架的一个RCE漏洞复现 ​框架简介 Symfony是一个开源的PHP Web框架,它现在是许多知名 CMS 的核心组件,例如Drupal、Joomla!、eZPlatform(以前称为 eZPublish)或Bolt。…

7、Qt5开发及实列(笔记2)

文章目录 1、mainwindow.c2、mainwindow.h 说明&#xff1a;此示例包含了基本的常使用的基本小部件 效果如下 1、mainwindow.c #include "mainwindow.h" #include <QApplication>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {widgetInit()…

深度Q网络(DQN)算法技术博客

深度Q网络&#xff08;DQN&#xff09;是一种将深度学习与强化学习相结合的算法&#xff0c;用于解决高维状态空间的强化学习问题。本文将详细介绍DQN算法的基本原理&#xff0c;关键公式以及具体的代码实现。 一、DQN算法的基本原理 DQN算法是Q学习的一种扩展&#xff0c;利…

小程序 npm 支持

使用 npm 包 目前小程序已经支持使用 npm 安装第三方包&#xff0c;因为 node_modules 目录中的包不会参与小程序项目的编译、 上传和打包&#xff0c;因此在小程序 项目中要使用的 npm 包&#xff0c;必须走一遍构建 npm 的过程。在构建成功以后&#xff0c;默认 会在小程序目…

Python面向对象编程中的继承及其应用

目录 1. 继承的基本概念 2. 继承的语法 3. 继承的应用场景 4. 使用示例&#xff1a;汽车销售系统 5. 总结 继承是面向对象编程中的一个重要概念&#xff0c;它允许我们根据已有类创建新类&#xff0c;并继承已有类的属性和方法。在本文中&#xff0c;我们将学习Python中的…

向量数据库、主键存储引擎、高速网络 RDMA 框架……DolphinDB 版本更新啦!

盛夏已至&#xff0c;炎热的七月伊始&#xff0c;DolphinDB 也迎来了版本的更新。此次更新的 3.00.1 与 2.00.13 版本从多个维度进行了优化扩展&#xff0c;进一步深化了 DolphinDB 在机器学习、数据分析等领域的尝试与探索。 为了响应用户日益增长的 AI 运算需求&#xff0c;…

Java基础:爬虫

1.本地爬虫 Pattern:表示正则表达式 Matcher:文本匹配器&#xff0c;作用按照正则表达式的规则去读取字符串&#xff0c;从头开始读取。在大串中去找符合匹配规则的子串。 1.2.获取Pattern对象 通过Pattern p Pattern.compile("正则表达式");获得 1.3.…

nginx重定向

nginx的重定向 location 匹配 location 匹配的就是后面的URI /wordpress location 匹配的分类和优先级** 1、精确匹配 location / 对字符串进行完全匹配&#xff0c;必须完全符合 2、正则匹配 ^~ 前缀匹配&#xff0c; 以什么开头 -区分大小写的匹配 ~*不区分大小写 …

Redis 五大数据类型底层原理

0、前言 本文涉及的主题&#xff1a; redis 对象存储 底层数据结构&#xff1a;int、embstr、raw、ziplist、listpack、quicklist、skiplist、intset、hashtable redis 数据类型&#xff1a;string、list、set、zset、hash 1、对象存储、底层编码、数据类型 1.1 对象存储…