2017 Multi-University Training Contest

来源:互联网 发布:基于代理模型的优化 编辑:程序博客网 时间:2024/05/29 16:44

http://acm.hdu.edu.cn/showproblem.php?pid=6097


题意:

  有一个圆心在原点的圆,给定圆的半径,给定PQ两点坐标(PO=QOPQ不在圆外),取圆上一点D,求PD+QD的最小值。

思路:

  考虑点在圆上的极端情况。做P点关于圆的反演点P,OPDODP相似,相似比是|OP|:rQ点同理。极小化PD+QD可以转化为极小化PD+QD。当PQ与圆有交点时,答案为两点距离,否则最优值在中垂线上取到。

代码:

#include<stdio.h>#include<math.h>const double eps = 1e-6;double dis(double x1,double y1,double x2,double y2){    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));}int main(){    int T;    double x1,y1,x2,y2,r;    while(~scanf("%d",&T)){        while(T--){            scanf("%lf %lf %lf %lf %lf",&r,&x1,&y1,&x2,&y2);            double op = dis(x1,y1,0,0);            if(op <= eps){                printf("%.7lf\n",r * 2);                continue;            }            double flag = r * r / (op * op);            double x3 = x1 * flag;            double y3 = y1 * flag;            double x4 = x2 * flag;            double y4 = y2 * flag;            double mx = (x3 + x4) / 2;            double my = (y3 + y4) / 2;            if(dis(mx,my,0,0) <= r){                double ans = dis(x3,y3,x4,y4);                printf("%.7lf\n",ans * op / r);            }else{                double x = mx * r / dis(mx,my,0,0);                double y = my * r / dis(mx,my,0,0);                double ans = dis(x1,y1,x,y);                printf("%.7lf\n",ans * 2.0);            }        }    }}