题解 P6039 【「ACOI2020」音速】(重制版)
Rubidium_Chloride
·
2020-02-03 23:26:00
·
题解
这是本人写的第一篇题解,有什么不足还请大家见谅
进博客食用更佳呦!
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;
}
```