跳到主要内容

题解:P8665 [蓝桥杯 2018 省 A] 航班时间

· 阅读需 3 分钟
lailai
Blogger

原题链接

参考资料

解题思路

时差建模

  1. 显然:
去程时间=飞行时间+时差回程时间=飞行时间时差\begin{aligned} \text{去程时间} = \text{飞行时间} + \text{时差} \\ \text{回程时间} = \text{飞行时间} - \text{时差} \end{aligned}
  1. 设飞行时间为 xx,去程时间为 t1t_1,回程时间为 t2t_2,时差为 kk,则有:
{t1=x+kt2=xk\begin{cases} t_1 = x + k \\ t_2 = x - k \end{cases}
  1. 两式相加得:
t1+t2=2xx=t1+t22t_1 + t_2 = 2x \Rightarrow x = \frac{t_1 + t_2}{2}
  1. 即飞行时间 xx 为去程时间 t1t_1 与回程时间 t2t_2 的平均值。

输入处理

  1. 利用 scanf 读入前半部分的时间:
scanf("%d:%d:%d %d:%d:%d",&h1,&m1,&s1,&h2,&m2,&s2);
  1. 若有后半部分的额外天数,两部分之间会存在空格,所以可以用 getchar 判断下一个字符是否为空格:
if(getchar()==' ')scanf("(+%d)",&d);
  1. 为便于计算,统一将时间转化为总秒数:
t=86400d+3600h+60m+st=86400d+3600h+60m+s

计算时间

分别利用 起飞时间 减去 降落时间,求出 去程时间回程时间,计算两者的平均值。

输出格式

  1. 将总秒数还原为时分秒:

设时分秒分别为 h,m,sh,m,s,显然 t=3600h+60m+st=3600h+60m+s

  • 因为 3600h3600h60m60m 都是 6060 的倍数,所以 s=tmod60s=t\bmod 60
  • 因为 3600h3600h36003600 的倍数,0s<600\le s<60,所以 mtmod360060<m+1m\le\frac{t\bmod 3600}{60}<m+1m=tmod360060m=\left\lfloor\frac{t\bmod3600}{60}\right\rfloor
  • 因为 0s,m<600\le s,m<60060m+s<36000\le60m+s<3600,所以 ht3600<h+1h\le\frac{t}{3600}<h+1h=t3600h=\left\lfloor\frac{t}{3600}\right\rfloor
  1. 利用 printf 格式化输出时间:
printf("%02d:%02d:%02d\n",ans/3600,ans%3600/60,ans%60);

参考代码

#include <bits/stdc++.h>
using namespace std;

int get()
{
int h1,m1,s1,h2,m2,s2,d=0;
scanf("%d:%d:%d %d:%d:%d",&h1,&m1,&s1,&h2,&m2,&s2);
if(getchar()==' ')scanf("(+%d)",&d);
return (d*86400+h2*3600+m2*60+s2)-(h1*3600+m1*60+s1);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int ans=get()+get()>>1;
printf("%02d:%02d:%02d\n",ans/3600,ans%3600/60,ans%60);
}
return 0;
}