给你一个中心在原点的圆,再给你俩在圆内且到原点距离相等的点P,Q,让你在圆上求一点D,最小化DP+DQ。
http://blog.csdn.net/qq_34845082/article/details/77099332
附:过反演中心的圆反演后变成一条和该圆正交的直线。
不过反演中心的圆反演后是一个与原圆关于反演中心位似的圆。
不过反演中心的直线反演后变成一个过反演中心且与其正交的圆。
#include<cstdio> #include<cmath> using namespace std; const double EPS=0.0000000001; struct Point{ double x,y; Point(){} Point(const double &x,const double &y){ this->x=x; this->y=y; } double length(){ return sqrt(x*x+y*y); } void read(){ scanf("%lf%lf",&x,&y); } }p,q; double R; typedef Point Vector; Vector unit(Vector v){ double l=v.length(); return Vector(v.x/l,v.y/l); } Point CalcMid(const Point &a,const Point &b){ return Point((a.x+b.x)*0.5,(a.y+b.y)*0.5); } double sqr(const double &x){ return x*x; } Vector operator - (const Point &a,const Point &b){ return Vector(a.x-b.x,a.y-b.y); } Vector operator * (const double &K,const Vector &v){ return Vector(K*v.x,K*v.y); } int T; int main(){ scanf("%d",&T); for(;T;--T){ scanf("%lf",&R); p.read(); q.read(); if(fabs(p.x)<EPS && fabs(p.y)<EPS){ printf("%.10lf\n",2.0*R); continue; } Point mp=CalcMid(p,q); Point P=Point((p-mp).length(),sqrt(sqr(p.length())-sqr((p-mp).length()))); Point Pp=R*R/P.length()*unit(P); if(Pp.y-R>EPS){ printf("%.10lf\n",P.length()/R*2.0*(Pp-Point(0.0,R)).length()); } else{ printf("%.10lf\n",P.length()/R*2.0*Pp.x); } } return 0; }
时间: 2024-10-03 22:40:45