每日一题——Python实现PAT乙级1058 选择题(举一反三+思想解读+逐步优化)6千字好文

news2024/11/17 21:56:40


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

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

Python-3.12.0文档解读

目录

我的写法

代码点评

时间复杂度分析

空间复杂度分析

总结

我要更强

空间复杂度优化

时间复杂度

总结

哲学和编程思想

抽象与模块化:

数据结构的选择:

预处理:

避免重复计算:

迭代与递增开发:

效率与性能优化:

错误处理与容错:

代码可读性与维护性:

测试与验证:

举一反三


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

我的写法

# 读取学生数量和问题数量
N_students_num, M_ques_num = map(int, input().split())

# 初始化一个字典来存储每个问题的答案信息
answers = {}
for i in range(M_ques_num):
    # 读取每个问题的完整分数、选项数量、正确选项数量和正确选项
    full_score, option_num, right_option_num, *right_options = input().split()
    # 将读取的字符串转换为整数
    full_score = int(full_score)
    option_num = int(option_num)
    right_option_num = int(right_option_num)
    # 将问题的答案信息存储在字典中
    answers[i+1] = [right_option_num, ''.join(right_options), full_score, option_num]

# 初始化一个字典来记录每个问题被错误回答的次数
ques_wrong_times = {i+1: 0 for i in range(M_ques_num)}

# 遍历每个学生
for i in range(N_students_num):
    # 读取学生的答案
    student_options = input()
    # 清理学生的答案,去除多余的空格和括号
    student_options = student_options.replace(' ', '').replace(')', '')
    student_options = student_options[1:].split('(')
    # 将学生的答案转换为正确的格式
    for j in range(M_ques_num):
        student_options[j] = int(student_options[j][0]), student_options[j][1:]

    # 计算学生的得分
    this_student_score = 0
    for j in range(M_ques_num):
        # 检查学生的答案是否正确,并计算得分
        if answers[j+1][0] == student_options[j][0] and answers[j+1][1] == student_options[j][1]:
            this_student_score += answers[j+1][2]
        else:
            # 如果答案错误,增加该问题的错误次数
            ques_wrong_times[j+1] += 1

    # 输出学生的得分
    print(this_student_score)

# 找出错误次数最多的问题
tmp = max(ques_wrong_times.values())
# 如果所有问题都被正确回答,输出"Too simple"
if tmp == 0:
    print("Too simple")
else:
    # 输出错误次数最多的问题的编号
    print(tmp, *[i for i in ques_wrong_times if ques_wrong_times[i] == tmp])

代码点评

这段代码的主要功能是处理学生的答案,计算每个学生的得分,并统计每个问题的错误次数。下面是对代码的专业点评:

  1. 输入处理:代码有效地处理了输入,包括解析学生数量、问题数量以及每个问题的详细信息。使用字典 answers 存储每个问题的答案信息,这是一个很好的做法,因为它允许快速查找。

  2. 答案解析:对于学生的答案,代码进行了适当的清理和解析,转换为便于比较的格式。这种预处理是必要的,以确保答案的正确比较。

  3. 得分计算:通过遍历每个学生的答案,代码计算了他们的得分。这是通过比较学生的答案和标准答案来完成的,逻辑清晰。

  4. 错误次数统计:使用字典 ques_wrong_times 来记录每个问题的错误次数,这是一个有效的数据结构选择,因为它允许快速更新和查询。

  5. 输出:代码正确地输出了每个学生的得分,并在最后输出了错误次数最多的问题。如果所有问题都被正确回答,则输出“Too simple”,这是一个很好的提示信息。

时间复杂度分析

  • 输入处理:O(M),其中 M 是问题数量。
  • 答案解析:O(N*M),其中 N 是学生数量。每个学生的答案需要与所有问题进行比较。
  • 得分计算和错误次数统计:O(N*M),因为每个学生的答案都需要与所有问题的答案进行比较。
  • 输出:O(M) 或 O(1),取决于是否需要输出错误次数最多的问题。

总时间复杂度为 O(N*M),这是因为在最坏的情况下,每个学生的答案都需要与所有问题的答案进行比较。

空间复杂度分析

  • 答案存储:O(M),用于存储所有问题的答案信息。
  • 错误次数统计:O(M),用于存储每个问题的错误次数。
  • 学生答案存储:O(N*M),因为每个学生的答案都需要存储。

总空间复杂度为 O(N*M),这是因为在最坏的情况下,需要存储所有学生的答案。

总结

这段代码在逻辑上是清晰的,有效地处理了输入和输出,并正确计算了学生的得分和问题的错误次数。时间复杂度主要受学生数量和问题数量的影响,而空间复杂度则主要受问题数量和学生答案的影响。在实际应用中,可能需要考虑优化策略,如使用更高效的数据结构或算法来减少时间和空间复杂度。


我要更强

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

  1. 使用集合(Set)来存储正确答案:这样可以快速检查学生的答案是否正确。
  2. 预处理学生的答案:将学生的答案转换为一种更易于比较的格式,例如使用字典或集合。
  3. 避免重复计算:如果可能,避免在每个学生的循环中重复计算相同的问题。

下面是优化后的代码:

# 读取学生数量和问题数量
N_students_num, M_ques_num = map(int, input().split())

# 初始化一个字典来存储每个问题的答案信息
answers = {}
for i in range(M_ques_num):
    full_score, option_num, right_option_num, *right_options = input().split()
    full_score = int(full_score)
    option_num = int(option_num)
    right_option_num = int(right_option_num)
    # 将问题的答案信息存储在字典中,使用集合存储正确答案
    answers[i+1] = {'full_score': full_score, 'options': set(right_options)}

# 初始化一个字典来记录每个问题被错误回答的次数
ques_wrong_times = {i+1: 0 for i in range(M_ques_num)}

# 遍历每个学生
for i in range(N_students_num):
    # 读取学生的答案
    student_answers = input().split()
    # 初始化学生的得分
    this_student_score = 0
    # 遍历每个问题
    for j in range(M_ques_num):
        # 学生的答案
        student_option = student_answers[j]
        # 正确答案
        correct_options = answers[j+1]['options']
        # 如果学生的答案在正确答案中,增加得分
        if set(student_option.split(' ')) == correct_options:
            this_student_score += answers[j+1]['full_score']
        else:
            # 如果答案错误,增加该问题的错误次数
            ques_wrong_times[j+1] += 1

    # 输出学生的得分
    print(this_student_score)

# 找出错误次数最多的问题
max_wrong_times = max(ques_wrong_times.values())
# 如果所有问题都被正确回答,输出"Too simple"
if max_wrong_times == 0:
    print("Too simple")
else:
    # 输出错误次数最多的问题的编号
    print(max_wrong_times, *[i for i in ques_wrong_times if ques_wrong_times[i] == max_wrong_times])

空间复杂度优化

使用集合存储正确答案:虽然集合可能需要更多的空间,但它在处理大量数据时提供了更快的查找速度。

时间复杂度

优化后的代码的总时间复杂度分析如下:

  1. 输入处理:O(M),其中 M 是问题数量。这里包括读取每个问题的答案信息并将其存储在字典中。
  2. 答案解析:O(M),这里我们将每个问题的正确答案转换为集合,这是一个线性操作。
  3. 得分计算和错误次数统计:O(NM),其中 N 是学生数量。对于每个学生,我们需要遍历所有问题来检查他们的答案是否正确,并更新错误次数。由于我们使用了集合来存储正确答案,检查一个答案是否正确的操作是 O(1),因此总的时间复杂度仍然是 O(NM)。
  4. 输出:O(M) 或 O(1),取决于是否需要输出错误次数最多的问题。

总时间复杂度为 O(N*M),这是因为在最坏的情况下,每个学生的答案都需要与所有问题的答案进行比较。尽管我们使用了集合来优化答案的检查过程,但由于每个学生的答案都需要遍历所有问题,因此总的时间复杂度保持不变。

总结

尽管我们在代码中使用了集合来优化答案的检查过程,但由于每个学生的答案都需要遍历所有问题,因此总的时间复杂度仍然是 O(N*M)。这是一个理论上的下界,因为我们需要检查每个学生的每个问题的答案。在实际应用中,这种优化可以显著提高处理大量数据时的性能。


哲学和编程思想

优化代码的过程中涉及了多种哲学和编程思想,以下是一些关键点:

  1. 抽象与模块化

    • 将问题的答案信息抽象为一个字典,每个问题作为一个键,其对应的值是一个包含答案详细信息的字典。这种抽象使得代码更加模块化,易于管理和扩展。
  2. 数据结构的选择

    • 使用集合(Set)来存储正确答案,利用了集合快速查找的特性。这是基于集合论的哲学思想,即通过集合的特性来简化问题。
  3. 预处理

    • 预先将问题的答案信息存储在数据结构中,以便后续快速访问。这种预处理的思想是基于“时间换空间”的哲学,即通过预先计算和存储结果来减少后续计算的时间。
  4. 避免重复计算

    • 通过预处理和使用合适的数据结构,避免了在每个学生的循环中重复计算相同的问题。这是基于“不要重复你自己”(Don't Repeat Yourself, DRY)的编程原则。
  5. 迭代与递增开发

    • 代码的开发过程中可能采用了迭代和递增的方法,即逐步增加功能并优化性能。这种开发方法是基于敏捷开发的哲学,强调持续改进和快速反馈。
  6. 效率与性能优化

    • 通过选择合适的数据结构和算法来优化时间复杂度,这是基于“算法效率”的哲学思想,即通过优化算法来提高程序的运行效率。
  7. 错误处理与容错

    • 代码中考虑了所有问题都被正确回答的情况,并给出了相应的输出。这种设计体现了容错和健壮性的思想,即程序应该能够处理各种输入情况,包括异常情况。
  8. 代码可读性与维护性

    • 通过添加注释和保持代码结构清晰,提高了代码的可读性和维护性。这是基于“代码是写给人看的”这一哲学,强调代码的可理解性和可维护性。
  9. 测试与验证

    • 在实际部署之前,代码应该经过充分的测试来验证其正确性和性能。这是基于“测试驱动开发”(Test-Driven Development, TDD)的哲学,强调在编写代码之前先编写测试用例。

通过这些哲学和编程思想的运用,我们可以创建出更加高效、可维护和健壮的代码。这些思想不仅适用于这个特定的优化问题,也适用于广泛的软件开发和编程实践中。


举一反三

基于上述哲学和编程思想以及本题目的具体情境,以下是一些实用的技巧和建议,可以帮助你在编程和问题解决中举一反三:

  1. 抽象与模块化

    • 在处理复杂问题时,首先识别问题中的关键组件和它们之间的关系。将这些组件抽象为函数或类,确保每个模块都有单一的责任。
    • 例如,在本题中,可以将读取输入、解析答案、计算得分和输出结果分别抽象为不同的函数,每个函数负责一个特定的任务。
  2. 数据结构的选择

    • 根据问题的特性选择合适的数据结构。在本题中,使用集合来存储正确答案是因为集合提供了快速的查找操作。
    • 在其他问题中,可能需要使用列表、字典、栈、队列等数据结构。了解每种数据结构的优缺点,并根据需要选择最合适的数据结构。
  3. 预处理

    • 对于可能重复使用的数据或计算结果,考虑进行预处理并存储结果,以便后续直接使用。
    • 例如,如果一个问题需要频繁查询某个数据集的最小值或最大值,可以预先计算并存储这些值。
  4. 避免重复计算

    • 识别并消除代码中的重复计算。在本题中,通过预先存储正确答案的集合,避免了在每个学生的循环中重复检查答案。
    • 在其他问题中,可能需要使用缓存、记忆化搜索等技术来避免重复计算。
  5. 迭代与递增开发

    • 采用迭代和递增的方法来开发程序。首先实现核心功能,然后逐步添加和优化其他功能。
    • 例如,在开发一个新功能时,可以先实现一个简单的版本,然后逐步添加错误处理、性能优化等。
  6. 效率与性能优化

    • 分析算法的时间和空间复杂度,寻找优化点。在本题中,通过使用集合来优化答案检查过程,提高了效率。
    • 在其他问题中,可能需要考虑更复杂的算法优化,如动态规划、贪心算法等。
  7. 错误处理与容错

    • 设计程序时考虑可能出现的异常情况,并提供适当的错误处理机制。
    • 例如,在读取文件或网络数据时,应该处理可能的IO错误,并提供有用的错误信息。
  8. 代码可读性与维护性

    • 编写清晰、有条理的代码,并添加必要的注释。确保代码易于理解和维护。
    • 例如,使用有意义的变量名,保持代码格式一致,使用版本控制工具来管理代码变更。
  9. 测试与验证

    • 在部署代码之前,进行充分的测试,包括单元测试、集成测试和性能测试。
    • 例如,为每个函数编写测试用例,确保它们按预期工作,并使用性能分析工具来检测潜在的性能瓶颈。

通过应用这些技巧,可以在面对不同编程问题时更加灵活和高效。记住,编程不仅仅是写代码,更是一种解决问题的方法和思维方式。

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

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

相关文章

【学习】开发板接口

工作用到机器的开发板 有如上三个接口 。最右是仿真器,中间是RS232串口,最左是电源线 仿真器 这个是仿真器 接入机器那端用的是SWD模式,另一端通过USB接电脑(这小肥手拍的怪好看)仿真口连接了四条线分别是 VCC&#…

gsap动画库对threejs模型的应用

前言 公司的一个3D编辑器项目,要在three模型上加一些补间动画。做了一些调研,最终选择了gsap,其丰富的缓动函数,强大的动画效果和兼容性,更适合公司的需求。 查看gsap文档,发现所有的例子都是针对dom元素…

【乐吾乐2D可视化组态编辑器】文件

1 文件 文件:文件的新建、打开、导入、保存、另存为、下载JOSN文件、下载ZIP打包文件、导出为HTML、导出为Vue2组件、导出为Vue3组件、导出为React组件(老版将不再维护)、下载为PNG、下载为SVG 乐吾乐2D可视化组态编辑器demo:ht…

振动分析-5-基于CNN的机械故障诊断方法

参考基于CNN的机械故障诊断方法 CNN之图像识别 预训练模型迁移学习(Transfer Learning) 基于卷积神经网络(CNN)的深度迁移学习在声发射(AE)监测螺栓连接状况的应用 参考基于CNN的机械故障诊断所面临的困难和…

安装GroudingDINO RuntimeError: Error compiling objects for extension,如何解决?

🏆本文收录于「Bug调优」专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&…

头条系统-05-延迟队列精准发布文章-概述添加任务(db和redis实现延迟任务)、取消拉取任务定时刷新(redis管道、分布式锁setNx)

文章目录 延迟任务精准发布文章1)文章定时发布2)延迟任务概述2.1)什么是延迟任务2.2)技术对比2.2.1)DelayQueue2.2.2)RabbitMQ实现延迟任务2.2.3)redis实现 3)redis实现延迟任务4)延迟任务服务实现4.1)搭建heima-leadnews-schedule模块4.2)数据库准备4.3)安装redis4.4)项目集成…

智能革新:AI写作工具如何重塑论文生成的艺术

在学术探索的征途中,AI论文工具本应是助力前行的风帆,而非让人陷入困境的漩涡。我完全理解大家在面对论文压力的同时,遭遇不靠谱AI工具的沮丧与无奈。毕竟,时间可以被浪费,但金钱和信任却不可轻弃。 作为一名资深的AI…

3. 向索引库中导入数据

1. 准备数据库对象 import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstr…

sheng的学习笔记-hive框架原理

需要学习的前置知识:hadoop 可参考 sheng的学习笔记-hadoop-CSDN博客 相关网址 官网:http://hive.apache.org 文档:https://cwiki.apache.org/confluence/display/Hive/GettingStarted https://cwiki.apache.org/confluence/display/Hive/…

Arcgis 计算经纬度坐标并补齐6位小数

工作中我们经常需要在Arcgis中计算点的经纬度或者线的起点、终点坐标,为确保数据的准确性,我们必须保留6位小数,但我们在默认计算的时候偶尔会遇到算出来的经纬度坐标小数位不足6位,那我们应该如何补齐呢,这里我将方法…

EE trade:贵金属投资的优点及缺点

贵金属(如黄金、白银、铂金和钯金)一直以来都是重要的投资和避险工具。它们具有独特的物理和化学特性,广泛应用于各种行业,同时也被视为财富储备。在进行贵金属投资时,了解其优点和缺点对于做出明智的投资决策至关重要。 一、贵金属投资的优…

【C++练级之路】【Lv.25】智能指针

快乐的流畅:个人主页 个人专栏:《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火,在为久候之人燃烧! 文章目录 一、智能指针的引入二、智能指针的概念1.1 RAII1.2 指针特性1.3 拷贝问题1.4 auto_ptr 三、智能指针的模拟实…

Linux基础 - 使用 ssh 服务管理远程主机(window linux vscode)

目录 零. 简介 一. 打开linux shh 二. window连接linux 三. linux连接linux 四. VSCode远程 零. 简介 SSH(Secure Shell)服务是一种网络协议,主要用于在不安全的网络环境中为计算机之间的通信提供安全的加密连接。 SSH 服务具有以下重要…

git 中有关 old mode 100644、new mode 10075的问题解决小结

问题: 同一个文件被修改后,最后代码没有变,文件变了,导致提交了一个空文件 git diff 提示 filemode 发生改变(old mode 100644、new mode 10075) 解决办法 : 原来是 filemode 的变化&#xff…

[leetcode]first-unique-character-in-a-string 字符串中的第一个唯一字符

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int firstUniqChar(string s) {unordered_map<int, int> frequency;for (char ch: s) {frequency[ch];}for (int i 0; i < s.size(); i) {if (frequency[s[i]] 1) {return i;}}return -1;} };

【Android】【Compose】Compose里面的Row和Column的简单使用

内容 Row和Column的简单使用方式和常用属性含义 Row 在 Jetpack Compose 中&#xff0c;Row 是一种用于在水平方向排列子元素的布局组件。它类似于传统 Android 中的 LinearLayout&#xff0c;但更加灵活和强大。 Row的代码 Composable inline fun Row(modifier: Modifier…

马斯克的SpaceX星舰有多牛?我们离殖民火星还有多远?

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 埃隆马斯克是一位知名的企业家和工程师&#xff0c;他掌握着多家公司&#xff0c;涉及多个领域&#xff0c;包括电动汽车、太空探索、太阳能、脑…

钉钉在MAKE 2024大会上宣布开放AI生态;NBC将用AI主播播报巴黎奥运会内容

&#x1f680; 钉钉在MAKE 2024大会上宣布开放AI生态 摘要&#xff1a;钉钉总裁叶军在MAKE 2024生态大会上宣布&#xff0c;钉钉将对所有大模型厂商开放&#xff0c;构建“国内最开放AI生态”。目前已有六家大模型厂商接入钉钉&#xff0c;用户可直接使用七家大模型产品。未来…

无人机赋能空间规划

城乡规划 高效构建实景三维模型&#xff0c;直 观反映地貌与建筑信息&#xff0c;辅 助设计人员进行科学规划。 业务挑战 BIM设计图、道路矢量图、卫星影像图无法进行精准匹配 传统测绘方式获得的二维图无法展示三维环境信息 BIM设计图与实景模型差异大&#xff0c;规划效…

Taro +vue3 中的微信小程序中的分享

微信小程序 右上角分享 的触发 以及配 useShareAppMessage(() > {return {title: "电影属全国通兑券",page: /pages/home/index,imageUrl: "http:///chuanshuo.jpg",};}); 置 就是Taro框架中提供的一个分享Api 封装好的