题目链接

时钟指针

题目描述

给定一个按时间先后顺序记录的时间序列,格式为 HH:MM:SS (24小时制)。我们需要计算每两个连续的时间点之间,秒针至少转了多少圈。

已知秒针每分钟(60秒)转一圈。

输入:

  • 第一行一个整数 ,表示时间点的个数。
  • 第二行 HH:MM:SS 格式的字符串。

输出:

  • 个浮点数,表示每两个相邻时间点之间秒针转过的圈数。

解题思路

这是一个时间计算问题。核心是计算出两个相邻时间点之间的最小时间差,然后根据“秒针每60秒转一圈”的规则换算成圈数。

1. 时间的表示

为了方便计算,最直接的方法是将所有 HH:MM:SS 格式的时间统一转换为从当天 00:00:00 开始的总秒数。 换算公式为:

2. 计算时间差

我们依次处理输入的时间点。假设当前时间点是 ,上一个时间点是 。我们将它们分别转换为总秒数

由于题目保证了时间序列是按先后顺序记录的,所以 的真实时刻一定晚于或等于 。这里有两种情况:

  • 情况一: 这说明 在同一天。那么它们之间经过的时间就是 秒。

  • 情况二: 这说明 必定是在 第二天。它们之间经过的时间包括:

    1. 到当天午夜 24:00:00 的时间。
    2. 从第二天 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}")

算法及复杂度

  • 算法:模拟 / 字符串处理
  • 时间复杂度:,其中 是时间点的数量。我们只需要遍历一次时间序列。
  • 空间复杂度:,用于存储所有输入的时间字符串。