这题上次补了以后忘记写博客了,现在补一下。
有两个注意点,第一是两圆相交的模板。可以通过任意一种情况手推出来。
第二是,实数二分要注意不用ans记录为妙,因为可能因为eps过小,导致ans无法进入记录答案的语句中(ans过大可能又会有误差),直接用一个l或者r记录一下即可。
代码如下:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <vector> 5 #include <math.h> 6 using namespace std; 7 const int N = 100000 + 100; 8 typedef long long ll; 9 const double eps = 1e-8; 10 const double pi = acos(-1.0); 11 12 double myabs(double x) {return x < 0 ? -x : x;} 13 14 double get(double a,double b,double x,double y,double R,double r) 15 { 16 double dx = myabs(a-x), dy = myabs(b-y); 17 double d = sqrt(dx*dx+dy*dy); 18 if(d > R + r) return 0.0; 19 if(R < r) swap(R,r); 20 if(d < R-r) return pi*r*r; 21 double A = 2.0*acos((R*R+d*d-r*r)/(2.0*R*d)); 22 double B = 2.0*acos((r*r+d*d-R*R)/(2.0*r*d)); 23 double s1 = 0.5*A*R*R + 0.5*B*r*r; 24 double s2 = 0.5*R*R*sin(A) + 0.5*r*r*sin(B); 25 return s1 - s2; 26 } 27 28 int main() 29 { 30 int T; 31 scanf("%d",&T); 32 while(T--) 33 { 34 double a,b,x,y,R; 35 scanf("%lf%lf%lf%lf%lf",&a,&b,&x,&y,&R); 36 double dx = myabs(a-x), dy = myabs(b-y); 37 double d = sqrt(dx*dx+dy*dy); 38 double Area = pi * R * R; 39 //double ans; 40 double l = 0.0, r = 100000000.0; 41 int T = 100; 42 while(T--) 43 { 44 double mid = (l+r) / 2.0; 45 double area = get(a,b,x,y,R,mid); 46 if(area*2.0 > Area) r = mid; //{ans = mid; r = mid;} 47 else l = mid; 48 } 49 printf("%.4f ",r); 50 //printf("%.4f ",ans); 51 } 52 return 0; 53 }