Skip to main content

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

· 2 min read
lailai
Student & Developer

参考资料

解题思路

时差

显然:

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

设飞行时间为 xx,去程时间为 t1t_1,回程时间为 t2t_2,时差为 kk,则有:

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

两式相加得:

t1+t2=2xx=t1+t22t_1+t_2=2x\Rightarrow x=\frac{t_1+t_2}{2}

不难发现,飞行时间 xx 为去程时间 t1t_1 与回程时间 t2t_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+st=86400d+3600h+60m+s

计算

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

输出

将总秒数还原为时分秒,设时分秒分别为 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=tmod360060m\le\frac{t\bmod 3600}{60}<m+1\Rightarrow m=\left\lfloor\frac{t\bmod3600}{60}\right\rfloor

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

ht3600<h+1h=t3600h\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;
}