勤怠の 記録から 残業と 深夜の 時間を出す
- 条件分岐
- 問題 19
- ふつう
- 目安 31 分
出勤と
本番の
入力は
問題
あるHH:MM の07:05 のように 0 を
- 退勤の
時刻が 出勤の 時刻より 前の ときは、 日を またいで、 出勤の 翌日の その 時刻に 退勤した ものとします。 出勤と 退勤が 同じ 時刻の 記録は ありません。 どの 勤務も 24 時間より 短くなります - 出勤から
退勤までの 分数を 勤務の 長さ、 勤務の 長さから 休憩 B を 引いた 分数を 実働と呼びます - 実働が 8 時間 (480 分) を
越えた とき、 越えた 分が その 勤務の 残業です。 越えなければ、 その 勤務の 残業は 0 分です - 毎日 22 時から
翌朝 5 時までを 深夜の 時間帯とします (0 時から 5 時までと、 22 時から 24 時までです)。 22 時 0 分ちょうどからの 1 分は 深夜に 入り、 5 時 0 分ちょうどからの 1 分は 深夜に 入りません。 出勤から 退勤までの うち、 深夜の 時間帯に 入る 分数が、 その 勤務の 深夜の 勤務分です - 休憩は、
深夜の 時間帯の 外で とった ものとします。 深夜の 勤務分から 休憩は 引きません
入力の形式
N
S_1 E_1 B_1
S_2 E_2 B_2
...
S_N E_N B_N1 行目に
出力の形式
2 行を
制約
- N は 1 以上 100000 以下の整数です
- S_i と E_i は
00:00以上23:59以下の時刻で、 S_i と E_i は 違う時刻です - B_i は 0 以上の
整数で、 その 勤務の 長さから 深夜の 勤務分を 引いた 値以下です (休憩は 深夜の 外でとれる 長さに 収まります)
入力と出力の例
例 1
1 件目は
入力
3 09:00 18:00 60 09:00 22:30 60 22:00 07:00 60
出力
270 450
例 2
朝 4 時に
入力
1 04:00 13:00 30
出力
30 60
ヒント
まだ開いていません
付箋は 3 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3答えに近い
全部の
先に
解答
時刻を 0 時からの
Python
Python
import sys
NIGHT = [(0, 300), (1320, 1740), (2760, 2880)]
def to_minutes(text):
return int(text[:2]) * 60 + int(text[3:])
data = sys.stdin.read().split()
n = int(data[0])
overtime = 0
night = 0
for i in range(n):
start = to_minutes(data[1 + 3 * i])
end = to_minutes(data[2 + 3 * i])
rest = int(data[3 + 3 * i])
if end < start:
end += 1440
overtime += max(0, end - start - rest - 480)
for low, high in NIGHT:
night += max(0, min(end, high) - max(start, low))
print(overtime)
print(night)JavaScript
JavaScript
const data = require("fs").readFileSync(0, "utf8").split(/\s+/).filter(Boolean);
const n = Number(data[0]);
const NIGHT = [[0, 300], [1320, 1740], [2760, 2880]];
const toMinutes = (text) => {
const [hour, minute] = text.split(":").map(Number);
return hour * 60 + minute;
};
let overtime = 0;
let night = 0;
for (let i = 0; i < n; i++) {
const start = toMinutes(data[1 + 3 * i]);
let end = toMinutes(data[2 + 3 * i]);
const rest = Number(data[3 + 3 * i]);
if (end < start) end += 1440;
overtime += Math.max(0, end - start - rest - 480);
for (const [low, high] of NIGHT) {
night += Math.max(0, Math.min(end, high) - Math.max(start, low));
}
}
console.log(overtime);
console.log(night);計算量
時間は O(N) です。Date でgetHours() と setMinutes() で 1
よく ある間違い
- 日を
またぐ 勤務で、 退勤から 出勤を 引いた 値が 負に なったまま 計算してしまう。 退勤が 出勤より 前なら 1440 を足します - 深夜を
「22 時以降」だけで 数えて、 朝 4 時に 出勤した ときの 4 時から 5 時を 数え落とす。 深夜の 時間帯は、 前の 夜から 続く 朝 5 時までの 分もあります - 22 時ちょうどや 5 時ちょうどの
境目を 1 分ずらす。 22 時 0 分からの 1 分は 深夜で、 5 時 0 分からの 1 分は 深夜では ありません - 残業を、
勤務の 長さから 休憩を 引かずに 480 と 比べてしまう - 22 時に
出勤して 翌日の 22 時より 後まで 働く 勤務で、 2 日目の 22 時からの 深夜を 数え落とす
解答を動かした版 Python 3.12.14Node.js 22.23.4確認日 2026/10/31