Mindis(hdu6097)

来源:互联网 发布:apache转发至python 编辑:程序博客网 时间:2024/06/05 17:36
Problem Description
The center coordinate of the circle C is O, the coordinate of O is (0,0) , and the radius is r.
P and Q are two points not outside the circle, and PO = QO.
You need to find a point D on the circle, which makes PD+QD minimum.
Output minimum distance sum.
 

Input
The first line of the input gives the number of test cases T; T test cases follow.
Each case begins with one line with r : the radius of the circle C.
Next two line each line contains two integers x , y denotes the coordinate of P and Q.

Limits
T500000
100x,y100
1r100
 

Output
For each case output one line denotes the answer.
The answer will be checked correct if its absolute or relative error doesn't exceed106.
Formally, let your answer be a, and the jury's answer be b. Your answer is considered correct if|ab|max(1,b)106.
 

Sample Input
444 00 440 33 040 22 040 11 0
 

Sample Output
5.65685435.65685435.8945030

6.7359174

给一个圆C和圆心O,P、Q是圆上或圆内到圆心距离相等的两个点,在圆上取一点D,求|PD| + |QD|的最小值

做点P、Q的反演点P'、Q', |OP| * |OP'| = r ^ 2, |OQ| * |OQ'| = r ^ 2.

|OP| / r = r / |OP'|, 即|OP| / |OD| = |OD| / |OP'|, 所以△OPD ∽ △ODP', 同理, △OQD ∽ △ODQ', 相似比为|OP| / r.

所以, |PD| + |QD| = (|P'D| + |Q'D|) * |OP| / r. 转化为求|P'D| + |Q'D|的最小值

若P'Q'与圆C有交点,则|P'D| + |Q'D|的最小值为|P'Q'| (此时D为P'Q'与圆C的交点, |P'D| + |Q'D| 为直线,值最小)

若P'Q'与圆C无交点,则D为PQ的中垂线与圆C的交点时, |P'D| + |Q'D|取得最小值(以P、Q为焦点做椭圆,令椭圆不断变大,椭圆与圆C有一个交点时,此交点即为点D)

这道题要用比例做 ,要用斜率找点很麻烦,有斜率等于0 或者没有斜率的情况

#include <iostream>#include <cstdio>#include <cmath>using namespace std;const double eps=1e-8;struct point{    double x,y;}p,q;double len(point a,point c){    return sqrt((a.x-c.x)*(a.x-c.x)+(a.y-c.y)*(a.y-c.y));}int main(){    int T;    double r;    scanf("%d", &T);    while (T-- )    {        scanf("%lf",&r);        scanf("%lf%lf",&p.x,&p.y);        scanf("%lf%lf",&q.x,&q.y);        point o;        o.x=0.0;        o.y=0.0;        double op=len(p,o);        point pp,qq,d;        if(abs(op)<=eps)        {            printf("%.6lf\n",r*2);        }        else        {            double l=r*r/op;            pp.x=p.x*l/op;            pp.y=p.y*l/op;            qq.x=q.x*l/op;            qq.y=q.y*l/op;            d.x=(pp.x+qq.x)/2;            d.y=(pp.y+qq.y)/2;            if(len(o,d)<=r)            {                double ans=len(pp,qq)*op/r;                printf("%.6lf\n",ans);            }            else            {                double dis=len(o,d);                double t=r/dis;                d.x=d.x*t;                d.y=d.y*t;                double ans=2*len(d,p);                printf("%.6lf\n",ans);            }        }    }    return 0;}

原创粉丝点击