【模板】圆相交面积
题目链接:https://vjudge.net/problem/HDU-3264
1 /************************************************************************* 2 > File Name: hdu3264.cpp 3 # File Name: hdu3264.cpp 4 # Author : xiaobuxie 5 # QQ : 760427180 6 # Email:760427180@qq.com 7 # Created Time: 2019年10月13日 星期日 17时00分36秒 8 ************************************************************************/ 9 10 #include<iostream> 11 #include<cstdio> 12 #include<map> 13 #include<cmath> 14 #include<cstring> 15 #include<set> 16 #include<queue> 17 #include<vector> 18 #include<algorithm> 19 using namespace std; 20 typedef long long ll; 21 #define inf 0x3f3f3f3f 22 #define eps 1e-6 23 #define pq priority_queue<int,vector<int>,greater<int> > 24 ll gcd(ll a,ll b){ 25 if(a<b) return gcd(b,a); 26 return b==0?a:gcd(b,a%b); 27 } 28 29 const int N = 30; 30 const double pi = acos(-1.0); 31 int n; 32 struct Circle{ 33 double x,y,r; 34 }p[N]; 35 double cir_area(Circle u,Circle v){ 36 double d = sqrt( (u.x - v.x)*(u.x - v.x) + (u.y - v.y)*(u.y - v.y)); 37 if( d >= u.r + v.r ) return 0; 38 else if( d <= fabs(u.r - v.r) ) return min(u.r,v.r) * min(u.r,v.r) * pi; 39 double a = acos( (u.r * u.r + d*d - v.r*v.r) / (2* u.r * d)); 40 double b = acos( (v.r * v.r + d*d - u.r*u.r) / (2* v.r * d)); 41 return u.r * u.r * a + v.r * v.r * b - u.r * d *sin(a); 42 } 43 bool judge(int id,double rr){ 44 Circle tem = (Circle){p[id].x,p[id].y,rr}; 45 for(int i = 1;i<=n;++i){ 46 double ss = cir_area(tem,p[i]); 47 if(ss < p[i].r * p[i].r * pi/2.0) return 0; 48 } 49 return 1; 50 } 51 int main(){ 52 int T; scanf("%d",&T); 53 while(T--){ 54 scanf("%d",&n); 55 for(int i = 1;i<=n;++i) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r); 56 double ans = 1e20; 57 for(int i = 1;i<=n;++i){ 58 double l = 0,r = 500000; 59 while( (r-l) > eps){ 60 double m = (l+r)/2; 61 if(judge(i,m)){ 62 ans = min(ans,m); 63 r = m; 64 } 65 else l = m; 66 } 67 } 68 printf("%.4f\n",ans); 69 } 70 return 0; 71 }