题解:

这里是用解析解的做法,

我们发现如果以P和Q做椭圆,那么当椭圆与圆相切的时候,答案最优

那么方程就是这样的

hdu6097 Mindis(几何)-LMLPHP

联立之后,解delta等于0,可以得到

hdu6097 Mindis(几何)-LMLPHP

答案就是2a了

注意不一定任何情况都有解,当delta等于0时,不一定存在那个点,这个时候显然就为中垂线与圆的交点,特判一下即可

此外点重合也要特判!

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int T;
struct point{
double x, y;
point() { x = y = ;}
point(double _x, double _y):x(_x), y(_y) { }
}p[];
const double eps = 1e-;
double dis(point A, point B){
return sqrt(pow(A.x - B.x, )+pow(A.y - B.y, ));
}
double r, c, t, a;
int main()
{
cin>>T;
while(T--){
scanf("%lf%lf%lf%lf%lf",&r,&p[].x,&p[].y,&p[].x,&p[].y);
c = dis(p[], p[])/;
t = sqrt(pow(dis(p[], p[]), ) - c*c);
a = r*c/sqrt(t*t+c*c);
if(abs(c) < eps){
point C = point(c, );
point D = point(, -r+t);
printf("%.10f\n", *dis(C, D));
continue;
}
if(abs(a - c) < eps) {
printf("%.10f\n", *a);
continue;
}
double B = *t*(a*a-c*c);
double A = c*c;
double Y = -B/A/;
if((Y-t)*(Y-t) - r*r > eps){
point C = point(c, );
point D = point(, -r+t);
printf("%.10f\n", *dis(C, D));
} else {
printf("%.10f\n", *a);
}
}
}
05-16 03:49