题解 P6039 【「ACOI2020」音速】(重制版)

· · 题解

这是本人写的第一篇题解,有什么不足还请大家见谅

进博客食用更佳呦!

0.前情提要

重制版,修了一下 \LaTeX 之类的内容。

1.题目大意

首先我们来概括一下题意:

输入两个数 x,y,以及一个半径 r,表示目的地的坐标和投掷的范围。

2.处理1

为了解决这个比较简单的问题,我们需要有一些数学的头脑。

注意题目中 “而且他们必须要传送后移动到杀老师的位置才能攻击它” 一句,表明他们必须使用传送器

两点之间直线最短。

所以我们可以顺其自然地想到要朝杀老师的方向投掷传送器!!

证明:

首先建立平面直角坐标系 xOy,先算出杀老师(位于 A 点)到学生们(位于 O 点)的欧几里得距离(dis)以及杀老师与学生的连线与 x 轴的夹角 \alpha,记朝 \alpha 方向掷出的传送器会将同学们传送至 B 点,既证 BA+OB 这段距离最短(尽管 OB 是传送的,但也相当于走过了,纳入计算)。

接下来分两种情况讨论:

如果 2\times r\le dis

若掷出传送器的角度 \theta\neq \alpha

则会将同学们传送至与 B 不同的点 B_1,学生们需要再从 B_1 走到 A,总路程为 OB_1+B_1A

因为三角形两边之和大于第三边,所以 OB_1+B_1A>OA=OB+BA

所以朝着 \alpha 方向扔是最有利的。

如果 2\times r> dis,此时传送器会将学生们传送至更远的地方了。

若掷出传送器的角度 \theta\neq \alpha

则会将同学们传送至与 B 不同的点 B_1,学生们需要再从 B_1 走到 A,总路程还是为 OB_1+B_1A

连接 BB_1,令 \angle OBB1=\beta\angle AB_1B=\gamma

因为 OB_1=OB=2\times r,所以\angle OB1B=\angle OBB1=β

所以 \gamma<\beta

运用正弦定理,可得 \dfrac{B_1A}{\sin\beta}=\dfrac{BA}{\sin\gamma}

因为 \sin\beta,\sin\gamma>0,且 \sin\beta>\sin\gamma

所以 B_1A>BA

综上,证毕。

3.处理2

在一大段的证明后,我们解决了本题的第一小问,接下来我们处理第二小问。

我们要研究的就是在单位圆意义下,\tan\alpha 到底代表什么?

答:\dfrac{y}{x}(纵坐标/横坐标)。

证明:令由原点引出的一条射线交单位圆于 C(x_1,y_1),与 x 轴正半轴夹角为 \alpha

\cos\alpha=x_1,\sin\alpha=y_1

## 4.处理3 本部分主要集中处理一些易错点。 1. 上节说过了,$\tan\alpha=\dfrac{y}{x}$,但是我们需要求的并不是$\tan\alpha$。 答案应该是 $\tan {90^\circ-α}$,所以答案是 $\dfrac{x}{y}$! 2. 题目提示里有 $\tan 90^\circ$ 无意义,输出`ERROR`,想必神仙们你都注意到了,但是,这个点并不是要说这个,而是要说一组特殊的数据。 ``` 0 0 1 ``` 你的程序输出是什么? 是 ``` 2.000000 ERROR ``` 吗? 那你就错了,正确的输出应该是: ``` 2.000000 0.00 ``` (解释:此时可以向**任意方向**投掷传送器,所以向 $x$ 轴正半轴方向投掷所得 $\tan\alpha=0$,最小。) ## 5.CODE (对于各位大佬来说,我的代码可能不太美观,还请大佬们原谅。) ```cpp #include<bits/stdc++.h> using namespace std; typedef long long ll; double x,y,r;double dis; int main(){ cin>>x>>y>>r; dis=abs(sqrt(x*x+y*y)-2*r); cout<<fixed<<setprecision(6)<<dis<<endl; if(y==0&&x==0) cout<<fixed<<setprecision(2)<<0.00<<endl; else if(y==0) cout<<"Error"<<endl; else cout<<fixed<<setprecision(2)<<abs(x/y)<<endl; return 0; } ```