题面

大秦为你打开题目传送门 (看不了的就看下面吧)

给定三维空间中的两个点 $A(x_1, y_1, z_1), B(x_2, y_2, z_2)$ ,以及点 $P(x, y, z)$ 。

计算点 $P$ 到线段 $AB$ 的最短距离。

思路

首先,三点确定一平面,此题一定有解。

其次,对于一个点与线段的关系,会有如下 $3$ 种。

而这一类型的题显然是用三分做的(我不介意你用数学方法做)

我们可以三分点与线段的最短线段的交点位置,然后求解。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<bits/stdc++.h>
using namespace std;

const double eps=1e-10;

double ax, ay, az, bx, by, bz, cx, cy, cz;

void Input(){
scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf", &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz);
}

double calc(double x, double y, double z){
return sqrt((x-cx)*(x-cx)+(y-cy)*(y-cy)+(z-cz)*(z-cz));
}

double Get(double mid){
double x=ax+mid*(bx-ax);
double y=ay+mid*(by-ay);
double z=az+mid*(bz-az);
return calc(x, y, z);
}

void Work(){
double l=0, r=1;
while(fabs(l-r)>eps){
// cout<<l<<' '<<r<<endl;
double mid1=l+(r-l)/3;
double mid2=r-(r-l)/3;
if(Get(mid1)-Get(mid2)>eps){
l=mid1;
}else{
r=mid2;
}
// cout<<l<<' '<<r<<endl;
}
printf("%.2lf\n", Get(l));
}

int main(){
int T;
scanf("%d", &T);
while(T--){
Input();
Work();
}
return 0;
}