题解:洛谷 B4000 休息时间

【题目来源】

洛谷:B4000 [GESP202406 一级] 休息时间 - 洛谷

【题目描述】

小杨计划在某个时刻开始学习,并决定在学习\(k\)秒后开始休息。

小杨想知道自己开始休息的时刻是多少。

【输入】

前三行每行包含一个整数,分别表示小杨开始学习时刻的时\(h\)、分\(m\)、秒\(s\)\(h\)\(m\)\(s\)的值符合\(1≤h≤12,0≤m≤59,0≤s≤59\))。

第四行包含一个整数\(k\)、表示小杨学习的总秒数(注:\(k\)的值符合\(1≤k≤3600\)

【输出】

输出一行,包含三个整数,分别表示小杨开始休息时刻的时、分、秒。

【输入样例】

12
59
59
10

【输出样例】

13 0 9

【核心思想】

  1. 问题分析:给定开始学习的时刻(时 \(h\)、分 \(m\)、秒 \(s\))和学习时长 \(k\) 秒,求开始休息的时刻。这是一个时间单位转换问题,核心在于将时分秒统一转换为秒进行计算,再转换回时分秒格式。

  2. 算法选择

    • 单位统一:将时分秒全部转换为总秒数,进行加法运算后再分解回时分秒
    • 取模分解:利用除法和取模运算将总秒数分解为时、分、秒
  3. 关键步骤

    • 读入数据:读取 \(h, m, s\)\(k\)
    • 转换为总秒数\(now \leftarrow h \times 3600 + m \times 60 + s\)
    • 加上学习时长\(now \leftarrow now + k\)
    • 分解回时分秒
      • \(hh \leftarrow now / 3600\)
      • \(now \leftarrow now \bmod 3600\)
      • \(mm \leftarrow now / 60\)
      • \(ss \leftarrow now \bmod 60\)
    • 输出结果\(hh, mm, ss\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(1)\)
    • 空间复杂度:\(O(1)\)
  5. 时间单位转换的核心思想

    • 统一单位简化运算:将复杂的多单位时间转换为单一单位(秒),避免时分秒分别进位的繁琐判断,将问题转化为简单的整数加法
    • 除法与取模的分解:利用 \(1\) 小时 \(= 3600\) 秒、\(1\) 分钟 \(= 60\) 秒的进制关系,通过整数除法提取高位单位,取模运算保留低位单位,实现从总秒数到时分秒的精确分解
    • 12小时制的隐含处理:题目中 \(h \in [1, 12]\),但输出样例显示 \(12:59:59 + 10\)\(= 13:00:09\),说明采用连续计时而非12小时循环,输出可超过12
    • 适用于多单位量的统一转换与分解类基础问题

【算法标签】

入门 #语法基础

【代码详解】

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int h, m, s;  // 当前时间:时、分、秒
    cin >> h >> m >> s;  // 输入当前时间

    int k;  // 要增加的秒数
    cin >> k;  // 输入增加的秒数

    // 将当前时间转换为总秒数
    int now = h * 60 * 60 + m * 60 + s;

    // 加上k秒
    now += k;

    // 计算新的时分秒
    int hh = now / 3600;  // 时 = 总秒数 ÷ 3600
    now %= 3600;          // 剩余的秒数

    int mm = now / 60;    // 分 = 剩余秒数 ÷ 60
    now %= 60;            // 剩余的秒数

    int ss = now;         // 秒 = 剩余秒数

    // 输出结果
    cout << hh << " " << mm << " " << ss << endl;

    return 0;
}

【运行详解】

12
59
59
10
13 0 9
posted @ 2026-07-16 16:37  团爸讲算法  阅读(18)  评论(0)    收藏  举报