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

· · 题解

参考资料

解题思路

时差

显然:

\begin{aligned} \text{去程时间}=\text{飞行时间}+\text{时差} \\ \text{回程时间}=\text{飞行时间}-\text{时差} \end{aligned}

设飞行时间为 x,去程时间为 t_1,回程时间为 t_2,时差为 k,则有:

\begin{cases} t_1=x+k \\ t_2=x-k \end{cases}

两式相加得:

t_1+t_2=2x\Rightarrow x=\frac{t_1+t_2}{2}

不难发现,飞行时间 x 为去程时间 t_1 与回程时间 t_2 的平均值。

输入

使用 scanf 读入前半部分的时间:

scanf("%d:%d:%d %d:%d:%d",&h1,&m1,&s1,&h2,&m2,&s2);

若有后半部分的额外天数,两部分之间会存在空格,所以可以用 getchar 判断下一个字符是否为空格:

if(getchar()==' ')scanf("(+%d)",&d);

为便于计算,将时间统一转化为总秒数:

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

计算

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

输出

将总秒数还原为时分秒,设时分秒分别为 h,m,s,显然:

t=3600h+60m+s

因为 3600h60m 都是 60 的倍数,所以:

s=t\bmod 60

因为 3600h3600 的倍数,而 0\le s<60,所以:

m\le\frac{t\bmod 3600}{60}<m+1\Rightarrow m=\left\lfloor\frac{t\bmod3600}{60}\right\rfloor

因为 0\le s,m<60\Rightarrow 0\le60m+s<3600,所以:

h\le\frac{t}{3600}<h+1\Rightarrow h=\left\lfloor\frac{t}{3600}\right\rfloor

使用 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;
}