HDU6097(数学题。。。。)

来源:互联网 发布:航运货代 知乎 编辑:程序博客网 时间:2024/06/06 18:37

看了题解好久,终于弄懂了,真的是菜。。。。直接上图:
这里写图片描述
过点P做P的反演点P1,使得OPOP1=OD2=r2

OPOD=ODOP1=DPDP1

所以只要求出DP1的最小值,就可以按比例求出DP。同理求出DQ1的最小值,就可以按比例求出DQ。也就是说题目转化成了求DP1+DQ1的最小值,两点之间直线最短,连接P1Q1,若与圆相交,则交点即为所求D。若不与圆相交,则PQ中垂线与圆的交点就是D。
判断P1Q1与圆的位置关系可以直接算圆心与线段P1Q1的距离与半径的大小即可。
code:

#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<iostream>#include<string>#include <set>//a&3==a%4using namespace std;#define ll long long#define mem(a) memset(a,0,sizeof(a))const double eps=1e-8;const int maxn=30010;//须填写const int inf=0x3f3f3f3f;double r,x,y;double len;struct Point//可以表示点与向量{    double x,y;    Point()    {        x=0;        y=0;    }    Point(double _x,double _y)    {        x=_x;        y=_y;    }};Point zero=Point(0.0,0.0);//(0,0)点bool judge1(Point a,Point b)//判断两点是否重合{    if(a.x==b.x&&a.y==b.y)        return true;    else        return false;}double dis(Point a,Point b)//两点间的距离{    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double chacheng(Point a,Point b)/*两点之间叉乘,用来求三角形OP1Q1的面积,进而求O到P1Q1的距离*/{    double res=a.x*b.y-b.x*a.y;    if(res-0>eps)    {        return res;    }    else{        return 0-res;    }}Point shucheng(Point a,double b)//数乘运算,用来求向量OP1,OQ1{    Point c=Point(a.x*b,a.y*b);    return c;}bool judge2(Point a,Point b){    double bili=r*r/dis(zero,a)/dis(zero,a);    Point a1=shucheng(a,bili);    Point b1=shucheng(b,bili);    double h=chacheng(a1,b1)/dis(a1,b1);    if(h-r>eps)        return false;    else return true;}int main(){    int kase;    scanf("%d",&kase);    while(kase--)    {        scanf("%lf",&r);        scanf("%lf%lf",&x,&y);        Point p=Point(x,y);        scanf("%lf%lf",&x,&y);        Point q=Point(x,y);        if(judge1(p,q))//判断两点是否重合        {            len=2*(r-dis(q,zero));        }        else if(judge2(p,q))//判断P1Q1与圆是否有交点        {//有的话求出P1Q1,然后按比例求出PQ            double bili=r*r/dis(zero,p)/dis(zero,p);            Point p1=shucheng(p,bili);            Point q1=shucheng(q,bili);            len=dis(p1,q1)*dis(p,zero)/r;        }        else{//没有的话PQ中垂线与圆的交点就是D            len=0;            Point mid=Point((p.x+q.x)/2.00,(q.y+p.y)/2.00);            double bili=r/dis(zero,mid);            mid=shucheng(mid,bili);            len=dis(mid,p)+dis(mid,q);        }        printf("%.7f\n",len);    }    return 0;}
原创粉丝点击