bnuoj 1053 EASY Problem (计算几何)

http://www.bnuoj.com/bnuoj/problem_show.php?pid=1053

【题意】:基本上就是求直线与圆的交点坐标

【题解】:这种题我都比较喜欢用二分,三分做,果然可以完爆,哈哈,特有成就感的说。。。

【code】:

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <math.h>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 #define eps 1e-12
  8 
  9 struct Point
 10 {
 11     double x,y;
 12     Point(){}
 13     Point(double dx,double dy)
 14     {
 15         x = dx;
 16         y = dy;
 17     }
 18 };
 19 
 20 double distance(double x1,double y1,double x2,double y2) //求距离
 21 {
 22     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
 23 }
 24 
 25 double distance2(double x1,double y1,double x2,double y2) //求距离的平方
 26 {
 27     return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
 28 }
 29 
 30 double area2(double x1, double y1, double x2, double y2, double x3,double y3)  //两倍三角形面积
 31 {
 32     double area;
 33     area = fabs(x1*y2+x2*y3+x3*y1-x3*y2-x1*y3-x2*y1);
 34     return area;
 35 }
 36 
 37 int isEqual(double a,double b)  //判断两浮点数是否相等
 38 {
 39     if(fabs(a-b)>1e-8)  return 0;
 40     return 1;
 41 }
 42 
 43 Point bs(double x1,double y1,double x2,double y2,double x3,double y3,double R)  //二分查找交点
 44 {
 45     double l=0,r=1,mid,x,y;
 46     while(l<=r)
 47     {
 48         mid = (l+r)/2;
 49         x = x1 + mid*(x2-x1);
 50         y = y1 + mid*(y2-y1);
 51         double temp =distance(x,y,x3,y3);
 52         if(temp<R) //与半径的距离为二分点
 53         {
 54             l=mid+eps;
 55         }
 56         else
 57         {
 58             r=mid-eps;
 59         }
 60     }
 61     return Point(x,y);
 62 }
 63 
 64 int main()
 65 {
 66     double Cx,Cy,R;
 67     double Px,Py;
 68     double Qx,Qy;
 69     scanf("%lf%lf%lf",&Cx,&Cy,&R);
 70     scanf("%lf%lf",&Px,&Py);
 71     scanf("%lf%lf",&Qx,&Qy);
 72     double area = area2(Px,Py,Qx,Qy,Cx,Cy);
 73     double disPQ = distance(Px,Py,Qx,Qy);
 74     double dis = area/disPQ;  //用面积除以底求得三角形的高,即点到直线的距离
 75     if(dis>R||isEqual(dis,R))  
 76     {
 77         puts("-1");
 78         return 0;
 79     }
 80     double x1,y1;
 81     x1 = Px-Qx;
 82     y1 = Py-Qy;
 83     double x=0,y=0,k=0,lx,rx,ry,ly;
 84     if(isEqual(Px,Qx))  //如果px==qx,不存在斜率
 85     {
 86         x = Px;
 87         y = (Cx-x)*x1/y1+Cy;
 88         lx = x;
 89         ly = Cy-R;
 90         rx = x;
 91         ry = Cy+R;
 92     }
 93     else if(isEqual(Py,Qy))  //存在斜率为1
 94     {
 95         y = Py;
 96         x = (Cy-y)*y1/x1+Cx;
 97         ly = Py;
 98         lx = Px-R;
 99         ry = Py;
100         rx = Px+R;
101     }
102     else //斜率在0-1之间
103     {
104         y = (Cy*y1/x1+Cx-Px+Py*(Qx-Px)/(Qy-Py))/(y1/x1+(Qx-Px)/(Qy-Py));
105         x = (Cy-y)*y1/x1+Cx;
106         lx = Cx - R;
107         ly = (Qy-Py)/(Qx-Px)*(lx-Px)+Py;
108         rx = Cx + R;
109         ry = (Qy-Py)/(Qx-Px)*(rx-Px)+Py;
110     }
111     Point p1 = bs(x,y,lx,ly,Cx,Cy,R);
112     Point p2 = bs(x,y,rx,ry,Cx,Cy,R);
113     double ans = distance2(p1.x,p1.y,Px,Py)+distance2(p2.x,p2.y,Px,Py);
114     printf("%.3lf\n",ans);
115     return 0;
116 }

 

posted @ 2013-09-29 22:18  crazy_apple  阅读(230)  评论(0编辑  收藏  举报