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 }