A - 時刻の正規化 / Time Normalization Editorial by admin
Claude 4.6 Opus (Thinking)概要
時刻データ(時 \(H\)、分 \(M\))が不正な値(分が60以上、時が24以上)になっている場合に、分→時→日の順に繰り上げ計算を行い、「\(D\) 日後の \(h\) 時 \(m\) 分」の形に正規化する問題です。
考察
この問題の本質は、日常で行う「繰り上がり」の計算です。
例えば、\(25\) 時 \(80\) 分という時刻データが与えられた場合を考えます。
手順1: 分の繰り上げ - \(80\) 分は \(60\) 分(\(= 1\) 時間)と \(20\) 分に分けられます - \(H' = 25 + \lfloor 80 / 60 \rfloor = 25 + 1 = 26\)(時) - \(m = 80 \bmod 60 = 20\)(分)
手順2: 時の繰り上げ - \(26\) 時は \(24\) 時間(\(= 1\) 日)と \(2\) 時間に分けられます - \(D = \lfloor 26 / 24 \rfloor = 1\)(日後) - \(h = 26 \bmod 24 = 2\)(時)
結果: 1 日後の 2 時 20 分 となります。
このように、整数の除算(切り捨て)と剰余演算だけで解けるため、特別なアルゴリズムは不要です。
注意点として、\(H\) や \(M\) が最大 \(10^9\) まであり得ますが、Python では整数のオーバーフローがないため、そのまま計算できます。C++ などの言語を使う場合は、\(H + \lfloor M / 60 \rfloor\) が32ビット整数の範囲を超える可能性があるため、64ビット整数を使う必要があります(最大で \(10^9 + \lfloor 10^9 / 60 \rfloor \approx 1.017 \times 10^9\) なので、この問題では32ビットでもギリギリ収まりますが、安全のため64ビットを使うのが良いでしょう)。
アルゴリズム
各予約データ \((H_i, M_i)\) に対して、問題文に書かれた手順通りに計算します。
- \(H' = H_i + \lfloor M_i / 60 \rfloor\) を計算する(分を時に繰り上げ)
- \(m = M_i \bmod 60\) を計算する(正規化後の分)
- \(D = \lfloor H' / 24 \rfloor\) を計算する(時を日に繰り上げ)
- \(h = H' \bmod 24\) を計算する(正規化後の時)
- \(D\), \(h\), \(m\) を出力する
計算量
- 時間計算量: \(O(N)\) — 各予約に対して定数回の演算を行うだけ
- 空間計算量: \(O(N)\) — 出力用のリストに結果を格納(1行ずつ出力すれば \(O(1)\) も可能)
実装のポイント
高速な入出力: \(N\) が最大 \(10^5\) のため、Python では
sys.stdin.readlineを使い、出力も1行ずつprintするのではなく、リストに溜めて最後に'\n'.join(out)でまとめて出力することで高速化しています。計算順序: 必ず「分の繰り上げ → 時の繰り上げ」の順に行います。順序を逆にすると正しい結果になりません。例えば、\(0\) 時 \(1500\) 分の場合、先に分を繰り上げて \(25\) 時 \(0\) 分とし、その後 \(1\) 日後の \(1\) 時 \(0\) 分とするのが正しい手順です。
ソースコード
import sys
input = sys.stdin.readline
N = int(input())
out = []
for _ in range(N):
H, M = map(int, input().split())
H_prime = H + M // 60
m = M % 60
D = H_prime // 24
h = H_prime % 24
out.append(f"{D} {h} {m}")
print('\n'.join(out))
この解説は claude4.6opus-thinking によって生成されました。
posted:
last update: