P14914 「QFOI R3」航线交汇 个人题解

题目链接

题目大意

给定 \(n+1\) 架飞机的起始位置和结束位置以及飞行的高度,要求第一架飞机与其他 \(n\) 架飞机在相同飞行时间内的距离是否在 \(d\) 的范围之内。

Solution

首先对于所有这 \(n\) 架飞机,必须满足飞行高度与第一架飞机的飞行高度差小于等于 \(d\),因为如果两架飞机飞行过程中就无法相互看到,那么全程一定无法看到,直接输出 No 就行。

然后,我们可以将每架飞机的运动看作关于时间 \(T\) 的线性函数。假设起飞时刻为 \(T=0\),降落时刻为 \(T=1\)
那么对于第 \(i\) 架飞机,它在时刻 \(T\in [0, 1]\) 的位置就可以表示为:\(s_{i}+(t_{i}-s_{i})T\),因为我们假设飞行时间为 \(1\),那么 \(t_{i}-s_{i}\) 就为该飞机的速度,所以经过时间 \(T\) 后飞机的位置就是初始位置加上飞行的高度。我们设 \(v_{i}=t_{i}-s_{i}\),于是位置就可以表示为 \(s_{i}+v_{i}T\)。当两架飞机的速度一样的时候,如果初始位置一样那么全程都可以看到,否则就全程无法看到。

如果速度不一样且满足高度条件,我们则需要寻找是否存在 \(T \in [0, 1]\) 使得 \(s_{1}+v_{1}T=s_{i}+v_{i}T\),则 \(T=\frac{s_{i}-s_{1}}{v_{1}-v_{i}}\),最后再用上面的公式得到相遇的距离为 \(s_{1}+v_{1}T\)。最后注意一个坑点,就是这道题需要输出小数点后 \(12\) 位,要注意精度问题,不然就会像我一样被卡好久。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	int x=0,f=1;
	char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}
int n=read(),d=read();
signed main(){
	int s0=read(),t0=read(),h0=read();
	for(int i=1;i<=n;i++){
		int s=read(),t=read(),h=read();
		if(abs(h-h0)>d){//判断飞行高度能否互相看到 
			puts("No");
			continue;
		}
		int v0=t0-s0,v=t-s;
		if(v0==v){//如果速度一样时 
			if(s==s0)//如果初始位置一样,那么全程都能看到 
				puts("Always");
			else//否则全程都看不到 
				puts("No");
		}
		else{
			double T=(double)(s-s0)/(v0-v);//计算相遇时间 
			if(T>=-1e-11 && T<=1.0+1e-11)//注意精度问题 
				printf("%.12lf\n",(double)s0+(double)v0*T);
			else
				puts("No");
		}
	}
	return 0;
}

posted @ 2025-12-28 19:21  See_you_soon  阅读(7)  评论(0)    收藏  举报