在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++


在这里插入图片描述


💯前言

  • 在这次学习中,逐步解决了两道 C++ 时间计算相关的题目,并针对每道题目进行了全面的解析、改进与总结。本文将详细梳理这些内容,涵盖题目的解读、代码实现、思路优化以及对一些概念的拓展。
    通过这次总结,可以更深入地理解时间计算的方式,并且如何通过代码实现高效的解决方案。这些题目的解析不仅有助于掌握时间转换与计算的技巧,还能提升编程中的逻辑推理能力
    C++ 参考手册
    在这里插入图片描述

💯第一题:秒数转换为小时、分钟、秒


题目描述

给定秒数,将其转换为小时、分钟和秒。

  • 时间限制:C/C++/Rust/Pascal 1秒,其他语言2秒
  • 空间限制:C/C++/Rust/Pascal 32M,其他语言64M
  • 64bit IO Format: %lld

输入描述:

  • 一行,包括一个整数,即给定的秒数。范围为 (0 < seconds < 1000000000)

输出描述:

  • 一行,包含三个整数,依次为输入整数对应的小时数、分钟数和秒数(可能为零),中间用一个空格隔开。

示例
输入:

3661

输出:

1 1 1

解题思路

在这里插入图片描述

这道题的要求非常明确,就是将一个给定的秒数转换为小时、分钟和秒数。解题的思路可以按照以下几个步骤进行:

  1. 输入解析:输入一个整数 seconds,表示总秒数。
  2. 计算小时数:通过整数除法 seconds / 3600,得到总的小时数。
  3. 计算剩余的分钟和秒数
    • 通过 seconds % 3600 计算剩余秒数。
    • 将剩余秒数再除以 60,得到分钟数,使用 seconds % 60 计算剩余的秒。
  4. 输出格式化:最后按照题目要求的格式输出小时、分钟、秒数。

代码实现

在这里插入图片描述


我的代码

以下是我使用的 C++ 实现代码:

#include <iostream>
using namespace std;

int main() {
    int seconds;
    cin >> seconds;

    // 输出小时、分钟和秒
    cout << seconds / 3600 << " " << (seconds % 3600) / 60 << " " << seconds % 60 << endl;

    return 0;
}

在这里插入图片描述


老师的代码

以下是老师的 C++ 实现代码:

#include <iostream>
using namespace std;

int main() {
    int seconds;
    cin >> seconds;

    // 输出小时、分钟和秒
    cout << seconds / 3600 << " " << (seconds / 60) % 60 << " " << seconds % 60 << endl;

    return 0;
}

在这里插入图片描述


代码对比与分析

  • 实现方式:我的代码实现方式都很简洁,将所有计算集中在一行中完成。老师的代码也将计算集中在一行中,但在计算分钟数时采用了不同的方式。

  • 分钟计算差异

    • 我的代码中计算分钟数的方式是 (seconds % 3600) / 60,即先通过取余 3600 得到剩余秒数,再除以 60 得到分钟数。
      在这里插入图片描述

    • 老师的代码中计算分钟数的方式是 (seconds / 60) % 60,即先将秒数转换为总分钟数,再通过取模 60 得到去除完整小时后的分钟数。
      在这里插入图片描述

    • 两种方式在逻辑上等价,都会得到相同的结果,只是计算顺序有所不同。

  • 可读性:两种代码的实现方式都较为简洁,但老师的写法在表达分钟数计算时,直接从总分钟数取模,逻辑上更加直接。

  • 数据类型选择:在老师的代码中,使用了 int 数据类型,这在题目给定的范围内((0 < seconds < 10^9))是足够的。


示例分析

对于输入 3661

  • 3661 秒可以转换为 1 小时 1 分钟 1 秒,所以输出为 1 1 1
    在这里插入图片描述

讨论与改进

在这里插入图片描述
分析了两种计算分钟数的方式,两者在结果上等价,但表达上有所不同。可以根据个人习惯选择适合的方式,但要确保逻辑的正确性代码的可读性

此外,可以考虑根据需要对代码进行一些扩展,例如:

  • 在输出时增加提示信息,让结果更加直观;
  • 将时间计算部分提取为函数,使代码更加模块化。

这样的改进在实际项目中不仅能提高代码的重用性,还可以显著提升可维护性


💯第二题:小鱼游泳时间计算


题目描述

伦敦奥运会要到了,小鱼在拼命练习游泳准备参加游泳比赛,可怜的小鱼并不知道鱼类是不能参加人类的奥运会的。

一天,小鱼给自己的游泳时间做了精确的计时(本题中的计时都按 24 小时制计算),它发现自己从 ab 分一直游泳到当天下午的 cd 分,请你帮小鱼计算一下,它这一天一共游了多少小时和多少分钟?

输入格式

  • 一行内输入四个整数,以空格隔开,分别表示题目中的 a, b, c, d
  • (0 \le a, c < 24, 0 \le b, d < 60),且结束时间一定晚于开始时间。

输出格式

  • 一行内输出两个整数 ef,用空格间隔,依次表示小鱼这天一共游了多少小时多少分钟。输出分钟数 f 应该小于 60

输入输出样例
输入:

12 50 19 10

输出:

6 20

说明/提示
对于全部测试数据,(0 \le a, c < 24, 0 \le b, d < 60),且结束时间一定晚于开始时间。


解题思路

在这里插入图片描述

  1. 输入解析

    • 输入包含四个整数 a, b, c, d,分别表示开始时间的小时和分钟,结束时间的小时和分钟。
  2. 时间转换

    • 将开始时间和结束时间都转换为当天经过的总分钟数,便于统一计算:
      • start_minutes = a * 60 + b
      • end_minutes = c * 60 + d
  3. 计算时间差

    • 计算 end_minutes - start_minutes 即为小鱼游泳的总时长。
    • 由于题目已保证结束时间一定晚于开始时间,因此不需要考虑跨午夜的情况。
  4. 转换结果

    • 将计算得到的分钟数转换为小时和分钟:
      • hours = duration_minutes / 60
      • minutes = duration_minutes % 60

代码实现

#include <iostream>
using namespace std;

int main() {
    int a, b, c, d;
    int sum_time, hour, minute;

    // 输入开始时间和结束时间
    cin >> a >> b >> c >> d;

    // 计算总时间差(以分钟为单位)
    sum_time = (c * 60 + d) - (a * 60 + b);

    // 转换为小时和分钟
    hour = sum_time / 60;
    minute = sum_time % 60;

    // 输出结果
    cout << hour << " " << minute << endl;

    return 0;
}

在这里插入图片描述


示例分析

  • 对于输入 12 50 19 10
    • 开始时间12 * 60 + 50 = 770 分钟。
    • 结束时间19 * 60 + 10 = 1150 分钟。
    • 时间差1150 - 770 = 380 分钟。
    • 转换为小时和分钟380 / 60 = 6 小时,380 % 60 = 20 分钟。
    • 输出6 20
      在这里插入图片描述

讨论与改进

在这里插入图片描述
原代码没有处理跨午夜的情况。但由于题目中明确说明了结束时间一定晚于开始时间,因此跨午夜逻辑在这里是多余的,直接省略,简化了实现,使代码更加简洁高效

此外,如果需要处理更复杂的情况,例如跨越午夜或者跨越多个小时,可以采用以下方法:

  • 将时间统一转换为一个更大的单位(如分钟);
  • 进行差值计算;
  • 最后将结果转换回小时和分钟的形式。

这种方法不仅可以轻松处理复杂的时间差问题,还能让代码在逻辑上更加清晰、灵活。


💯小结

  1. 在这里插入图片描述
    明确题目条件:通过仔细阅读题目,确保理解题目给出的条件,例如第二题中结束时间晚于开始时间,使得不需要考虑跨午夜的情况,从而简化了解题逻辑。

  2. 代码实现:对于时间计算,转换为统一单位(如总分钟数)可以大大简化计算的复杂度,使得解决问题更加直接和高效。

  3. 图示理解与逻辑分析:绘制图解有助于更好地理解小时、分钟和秒数的拆分与计算,图示对于理解问题的整体逻辑非常有帮助。

  4. 优化代码的可读性:无论是第一题的秒数转换,还是第二题的游泳时间计算,都尽量保持代码清晰、可读,逻辑步骤分明,变量命名合理,这对后续的维护和调试都十分有益。

  5. 自信与思考:逻辑清晰且富有创造性,这种自信和思考能力是非常宝贵的,不仅有助于解决问题,还能帮助更深入地掌握编程技巧。通过反复练习与思考,不仅掌握了编程的核心技能,还能在不断挑战中提高解决复杂问题的能力。

  6. 持续改进与扩展:在编码过程中,始终要考虑代码的扩展性和可维护性,尤其是在处理复杂逻辑时。例如,处理时间问题时,考虑跨越多日、多时间段的情况,这样的考虑将帮助在实际应用中应对更多的不确定性和复杂性。代码的模块化设计和函数化封装也是提升代码质量的重要方法。

总之,通过对这两道题目的解答,可以更深入地掌握时间转换与计算的技巧,并学习到如何在明确题目条件的前提下进行优化。继续保持这种细心条理清晰的学习方式,一定能在编程的道路上越走越远。不论是简单的时间转换问题,还是复杂的逻辑推理问题,只要持续深入学习并不断挑战自我,就能在编程领域不断取得进步,迈向更高的目标。


在这里插入图片描述


Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐