官方题解:BestCoder Blog
图片来源于:No Rain,No L’Arc~en~Ciel
代码:
#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-10;
const double PI = acos(-1.0);
struct Point { double x, y; Point(double x=0, double y=0):x(x),y(y) {} };
struct Circle { Point c; double r; Circle(Point c=Point(0, 0), double r = 0):c(c),r(r) {} };
typedef Point Vector;
int dcmp(double x) { if(fabs(x) < eps) return 0; else return x<0?-1:1; }
bool operator < (const Point& a, const Point& b) { return a.x<b.x || (a.x==b.x&&a.y<b.y); }
bool operator == (const Point& a, const Point& b) { return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0; }
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Angle(Vector A, Vector B) { return acos(Dot(A, B)/Length(A)/Length(B)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
int main() {
int T;
scanf("%d", &T);
while(T--) {
double r;
Point P, Q;
scanf("%lf%lf%lf%lf%lf", &r, &P.x, &P.y, &Q.x, &Q.y);
double lenP = Length(P);
double x = r*r/lenP;
Point P0 = { P.x/lenP*x, P.y/lenP*x };
Point Q0 = { Q.x/lenP*x, Q.y/lenP*x };
Point D = (P0+Q0)/2.0;
double lenD = Length(D), ans;
if(P == Q) ans = 2*(r-lenP);
else if(lenD <= r) ans = Length(P0-Q0)*r/x;
else {
D = {D.x/lenD*r, D.y/lenD*r};
ans = Length(D-P)+Length(D-Q);
}
printf("%.10f\n", ans);
}
return 0;
}