题目链接
题目描述
给定一个按时间先后顺序记录的时间序列,格式为 HH:MM:SS
(24小时制)。我们需要计算每两个连续的时间点之间,秒针至少转了多少圈。
已知秒针每分钟(60秒)转一圈。
输入:
- 第一行一个整数
,表示时间点的个数。
- 第二行
个
HH:MM:SS
格式的字符串。
输出:
个浮点数,表示每两个相邻时间点之间秒针转过的圈数。
解题思路
这是一个时间计算问题。核心是计算出两个相邻时间点之间的最小时间差,然后根据“秒针每60秒转一圈”的规则换算成圈数。
1. 时间的表示
为了方便计算,最直接的方法是将所有 HH:MM:SS
格式的时间统一转换为从当天 00:00:00
开始的总秒数。
换算公式为:
2. 计算时间差
我们依次处理输入的时间点。假设当前时间点是 ,上一个时间点是
。我们将它们分别转换为总秒数
和
。
由于题目保证了时间序列是按先后顺序记录的,所以 的真实时刻一定晚于或等于
。这里有两种情况:
-
情况一:
这说明
和
在同一天。那么它们之间经过的时间就是
秒。
-
情况二:
这说明
必定是在
的第二天。它们之间经过的时间包括:
- 从
到当天午夜
24:00:00
的时间。 - 从第二天
00:00:00
到的时间。 总时间差为
秒。
- 从
3. 计算圈数
秒针每 60 秒转一圈。所以,将上面计算出的时间差 除以 60,即可得到秒针转动的圈数。
圈数 = \Delta S / 60.0
注意,结果要求是高精度的浮点数。
代码
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
using namespace std;
long long parse_time_to_seconds(const string& s) {
long long h = stoll(s.substr(0, 2));
long long m = stoll(s.substr(3, 2));
long long sec = stoll(s.substr(6, 2));
return h * 3600 + m * 60 + sec;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
vector<string> times(n);
for (int i = 0; i < n; ++i) {
cin >> times[i];
}
long long seconds_in_day = 24 * 3600;
for (int i = 1; i < n; ++i) {
long long prev_s = parse_time_to_seconds(times[i-1]);
long long curr_s = parse_time_to_seconds(times[i]);
long long diff_s;
if (curr_s >= prev_s) {
diff_s = curr_s - prev_s;
} else {
diff_s = (seconds_in_day - prev_s) + curr_s;
}
double rotations = static_cast<double>(diff_s) / 60.0;
cout << fixed << setprecision(10) << rotations << endl;
}
return 0;
}
import java.util.Scanner;
public class Main {
public static long parseTimeToSeconds(String s) {
String[] parts = s.split(":");
long h = Long.parseLong(parts[0]);
long m = Long.parseLong(parts[1]);
long sec = Long.parseLong(parts[2]);
return h * 3600 + m * 60 + sec;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String[] times = new String[n];
for (int i = 0; i < n; i++) {
times[i] = sc.next();
}
long secondsInDay = 24 * 3600;
for (int i = 1; i < n; i++) {
long prevS = parseTimeToSeconds(times[i - 1]);
long currS = parseTimeToSeconds(times[i]);
long diffS;
if (currS >= prevS) {
diffS = currS - prevS;
} else {
diffS = (secondsInDay - prevS) + currS;
}
double rotations = (double) diffS / 60.0;
System.out.printf("%.10f\n", rotations);
}
}
}
def parse_time_to_seconds(s):
h, m, sec = map(int, s.split(':'))
return h * 3600 + m * 60 + sec
n = int(input())
times = input().split()
seconds_in_day = 24 * 3600
for i in range(1, n):
prev_s = parse_time_to_seconds(times[i-1])
curr_s = parse_time_to_seconds(times[i])
diff_s = 0
if curr_s >= prev_s:
diff_s = curr_s - prev_s
else:
diff_s = (seconds_in_day - prev_s) + curr_s
rotations = diff_s / 60.0
print(f"{rotations:.10f}")
算法及复杂度
- 算法:模拟 / 字符串处理
- 时间复杂度:
,其中
是时间点的数量。我们只需要遍历一次时间序列。
- 空间复杂度:
,用于存储所有输入的时间字符串。