跳到主要内容

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

· 阅读需 2 分钟
lailai
Blogger

原题链接

参考资料

解题思路

1. 时差

  1. 显然,去程时间 == 飞行时间 ++ 时差;回程时间 == 飞行时间 - 时差。

  2. 设飞行时间为 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=2xt_1+t_2=2x

x=t1+t22x=\dfrac{t_1+t_2}{2}

  1. 所以飞行时间 xx 等于去程时间 t1t_1 和 回程时间 t2t_2 的平均值。

2. 读入

  1. scanf 读入前半部分的时间:
scanf("%d:%d:%d %d:%d:%d",&h1,&m1,&s1,&h2,&m2,&s2);
  1. 观察数据发现,如果有后半部分的额外天数,则两部分之间会有个空格。所以可以用 getchar 判断下一个字符是否为空格。如果是,用 scanf 读入天数。
if(getchar()==' ')scanf("(+%d)",&d);
  1. 为方便计算,不妨把时间都转换成总秒数:

t=86400d+3600h+60m+st=86400d+3600h+60m+s

3. 计算

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

4. 输出

  1. 将总秒数转换成时分秒。

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

  • 因为 3600h3600h60m60m6060 的倍数,所以 tmod60=st\bmod 60=s
  • 因为 3600h3600h36003600 的倍数,0s<600\le s<60,所以 mtmod360060=60m+s60<m+1m\le\dfrac{t\bmod 3600}{60}=\dfrac{60m+s}{60}<m+1tmod360060=m\left\lfloor\dfrac{t\bmod3600}{60}\right\rfloor=m
  • 因为 0s,m<600\le s,m<60,所以 060m+s<36000\le60m+s<3600,所以 ht3600<h+1h\le\dfrac{t}{3600}<h+1t3600=h\left\lfloor\dfrac{t}{3600}\right\rfloor=h
  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;
}