#19274. 环球飞行

环球飞行

题目名称:环球飞行 (Global Flight)

题目描述

在初中地理课上,小杨学习了“时区”的概念。全球被划分为 24 个时区,以本初子午线为基准,向东为东 1 区至东 12 区(记为 +1⋯+12+1 \dots +12),向西为西 1 区至西 11 区(记为 −1⋯−11-1 \dots -11),中时区记为 00。

两个时区之间的区时差等于它们的时区数值之差。 例如:

  • 北京(+8+8 区)和伦敦(00 区)差 8−0=88 - 0 = 8 小时。
  • 北京(+8+8 区)和纽约(−5-5 区)差 8−(−5)=138 - (-5) = 13 小时。

小杨计划进行一次环球飞行。他从第 0 天的起飞时间出发,经过 NN 段航程,每段航程会飞往一个新的时区。

已知:

  1. 当你到达一个新城市时,你需要将手表调整为当地的区时。
  2. 调整公式:当地到达时间 = 上一站起飞时的当地时间 + 飞行时长 + (新时区 - 旧时区)。
  3. 如果计算出的时间超过 24:00,则进入下一天(日期+1);如果小于 00:00,则退回前一天(日期-1)。

请你编写程序,根据给定的起始时间和飞行计划,计算出小杨最终落地时的当地日期和当地时间。

输入格式

第一行包含 4 个整数 N,Z0,H0,M0N, Z_0, H_0, M_0。

  • NN 表示航程段数。
  • Z0Z_0 表示起飞城市的时区(−11≤Z0≤12-11 \le Z_0 \le 12)。
  • H0:M0H_0 : M_0 表示第 0 天的起飞时间(2424小时制,0≤H0≤23,0≤M0≤590 \le H_0 \le 23, 0 \le M_0 \le 59)。

接下来 NN 行,每行包含 3 个整数 Hi,Mi,ZiH_i, M_i, Z_i。

  • Hi,MiH_i, M_i 表示第 ii 段航程的飞行时长为 HiH_i 小时 MiM_i 分钟。
  • ZiZ_i 表示第 ii 段航程的目的地时区。

输出格式

输出一行,格式为 Day D HH:MM。

  • DD 为落地时的日期(从第 0 天开始计算,可能是负数,也可能是正数)。
  • HH:MMHH:MM 为落地时的当地时间(小时和分钟不足两位需补0)。

输入输出样例 #1

输入:

2 8 9 30
12 0 -5
3 30 8

输出:

Day 1 01:00

样例 #1 修正解释:

  1. 初始状态:第 0 天 09:30,位于 +8+8 区。
  2. 第一段航程:飞往 −5-5 区,飞行 12 小时。
    • 飞行流逝时间:09:30+12h=21:3009:30 + 12h = 21:30。
    • 时区调整:从 +8+8 到 −5-5,时差为 (−5)−8=−13(-5) - 8 = -13 小时。
    • 落地当地时间:21:30−13h=08:3021:30 - 13h = 08:30。
    • 日期仍为第 0 天。
  3. 第二段航程:飞回 +8+8 区,飞行 3 小时 30 分。
    • 飞行流逝时间:08:30+3h30m=12:0008:30 + 3h30m = 12:00。
    • 时区调整:从 −5-5 到 +8+8,时差为 8−(−5)=+138 - (-5) = +13 小时。
    • 落地当地时间:12:00+13h=25:0012:00 + 13h = 25:00。
    • 进位:25:0025:00 超过了 24 点,变成第 1 天的 01:0001:00。

输入输出样例 #2

输入:

1 0 23 0
2 0 -1

输出:

Day 1 00:00

解释:23:00+2h+(−1−0)h=25:00−1h=24:0023:00 + 2h + (-1 - 0)h = 25:00 - 1h = 24:00,即次日 00:0000:00。

数据范围

对于 100%100\% 的数据,保证 1≤N≤1001 \le N \le 100,0≤Hi≤1000 \le H_i \le 100。时区 ZZ 在 [−11,12][-11, 12] 之间。

背景知识

为了帮助你更好地理解和解答有关“时区”的编程题目,以下整理了初中地理中关于时区的核心背景知识,以及在**信息学奥赛(OI)**中处理此类问题时的注意事项。


1. 为什么会有时区?

地球是一个球体,并且不停地自西向东自转。这就导致了地球上不同经度的地方,看到太阳升起的时刻是不同的:

  • 东边的地方比西边先看到日出。
  • 东边的时间比西边早(数值更大)。

为了方便各国的交流和计时,国际上人为规定了“时区”系统。

2. 时区的划分规则(理论基础)

  • 经度与时间:地球一圈是 360∘360^\circ,一天是 24 小时。360∘÷24=15∘360^\circ \div 24 = 15^\circ 因此,经度每隔 15度,时间就相差 1 小时。
  • 中时区(零时区):以本初子午线(0∘0^\circ 经线,经过英国伦敦格林尼治天文台)为基准,向东、西各跨 7.5 度。
  • 东时区:从中时区向东,依次为东 1 区至东 12 区。
  • 西时区:从中时区向西,依次为西 1 区至西 12 区。
  • 东西十二区:东 12 区和西 12 区各跨 7.5 度,合为一个时区(180度经线),时刻相同,但日期相差一天。

3. 编程中的数值化处理

在编程和数学计算中,我们通常用整数来表示时区:

时区名称 符号表示 备注
东 NN 区 +N+N 例如北京是东八区 (+8+8)
中时区 00 伦敦、格林尼治标准时间 (GMT/UTC)
西 NN 区 −N-N 例如纽约是西五区 (−5-5)

4. 区时的计算公式(核心考点)

公式:

$$\text{所求时区时间} = \text{已知时区时间} + (\text{所求时区} - \text{已知时区}) $$

理解要点:

  1. “所求 - 已知”:
    • 这就是两个时区的差值。
    • 如果是向东算(去时区数值更大的地方),差值为正,时间增加。
    • 如果是向西算(去时区数值更小的地方),差值为负,时间减少。
  2. 同减异加:
    • 同在东时区或同在西时区,时区数相减。
    • 一个在东一个在西,数值相加(因为一个是正数一个是负数,减负数等于加正数)。

举例:

  • 例1(同侧):已知北京(+8+8)是 12:00,求东京(+9+9)。12:00+(9−8)=13:0012:00 + (9 - 8) = 13:00
  • 例2(异侧):已知北京(+8+8)是 12:00,求纽约(−5-5)。12:00+(−5−8)=12:00−13=−1:0012:00 + (-5 - 8) = 12:00 - 13 = -1:00 注意:−1:00-1:00 表示前一天的 23:00。

5. 国际日期变更线(日界线)

  • 大致以 180°经线 为界。
  • 它是地球上“今天”和“昨天”的分界线。
  • 向东越过日界线(从东12区去西12区):日期 减 1 天。
  • 向西越过日界线(从西12区去东12区):日期 加 1 天。
  • 编程提示:在纯时区计算题(如上一道题)中,通常不需要特意处理这条线,只要按照 +12+12 和 −12-12 的数值逻辑计算,日期进位/借位会自动符合这个规律。

6. 现实与编程的区别(OIer 需要注意的坑)

  1. 行政时区 vs 理论时区:
    • 理论:严格按经度每 15 度划分。
    • 现实:为了管理方便,一个国家可能统一使用一个时区。
    • 例子:中国横跨 5 个时区,但统一使用北京时间(东八区)。编程题除非特指经度,否则通常直接给出时区编号。
  2. 半时区(非整数时区):
    • 有些国家的时间不是整点,而是半点。
    • 例子:印度是 +5.5+5.5 区(东五点五区)。
    • 编程策略:如果题目涉及半时区,建议全部化为分钟进行计算,避免浮点数误差。
  3. 夏令时 (Daylight Saving Time):
    • 欧美国家夏天会把时间人为拨快 1 小时。
    • 编程策略:除非题目明确提到“考虑夏令时”,否则OI题目默认不考虑夏令时。

7. 总结:做这类题的通法

遇到“时区计算”或“环球飞行”类题目,最稳健的步骤是:

  1. 统一基准:将所有时间转换为UTC (0时区) 的时间,或者转化为相对于第0天00:00的总分钟数。
  2. 纯数学计算:在统一的基准上进行加减。
  3. 还原格式:最后再根据目标时区,将总分钟数还原为 Day HH:MM 格式。
  4. 处理取模:熟练掌握 (a % b + b) % b 来处理时间倒流导致的负数问题。