题解:洛谷 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
【核心思想】
-
问题分析:给定开始学习的时刻(时 \(h\)、分 \(m\)、秒 \(s\))和学习时长 \(k\) 秒,求开始休息的时刻。这是一个时间单位转换问题,核心在于将时分秒统一转换为秒进行计算,再转换回时分秒格式。
-
算法选择:
- 单位统一:将时分秒全部转换为总秒数,进行加法运算后再分解回时分秒
- 取模分解:利用除法和取模运算将总秒数分解为时、分、秒
-
关键步骤:
- 读入数据:读取 \(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\)
-
时间/空间复杂度:
- 时间复杂度:\(O(1)\)
- 空间复杂度:\(O(1)\)
-
时间单位转换的核心思想:
- 统一单位简化运算:将复杂的多单位时间转换为单一单位(秒),避免时分秒分别进位的繁琐判断,将问题转化为简单的整数加法
- 除法与取模的分解:利用 \(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
浙公网安备 33010602011771号