杭电 3264(相交圆求面积模板)

来源:互联网 发布:手机淘宝怎么加淘友 编辑:程序博客网 时间:2024/06/07 09:18
//就是找一个圆(圆心为给出的圆中的一个),满足覆盖其他所有的圆至少一般的面积#include<stdio.h>#include<math.h>#define INF 100000000#define EPS 1e-8  #define PI 3.1415926struct POINT{double x,y,r;}cir[30];int n;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 crossarea(POINT a,double ra,POINT b,double rb) //圆相交的面积{double ans=0;double d=dis(a,b);    double temp;if(ra<rb){temp=ra;ra=rb;rb=temp;}if(d>=(ra+rb))    //相隔return 0;    if(d<=(ra-rb))    // 内含return PI*rb*rb;    double angle1=acos((ra*ra+d*d-rb*rb)/2.0/ra/d);  double angle2=acos((rb*rb+d*d-ra*ra)/2.0/rb/d);      ans-=d*ra*sin(angle1);      ans+=angle1*ra*ra+angle2*rb*rb;  return ans;  }bool istrue(int j,double r)    // 判断j为圆心,半径为r是否满足条件{for(int i=0;i<n;i++){double area=crossarea(cir[j],r,cir[i],cir[i].r);if(area<0.5*PI*cir[i].r*cir[i].r)return false;}return true;}double getr(int i) {double left,right,mid;left=0;right=5000;while(left+EPS<=right){mid=(left+right)/2;if(istrue(i,mid))  right=mid-EPS;elseleft=mid+EPS;}return mid;}int main(){int i,t;scanf("%d",&t);while(t--){scanf("%d",&n);for(i=0;i<n;i++)scanf("%lf%lf%lf",&cir[i].x,&cir[i].y,&cir[i].r);        double ans=INF;for(i=0;i<n;i++)        {double radio=getr(i);if(radio<ans)ans=radio;}printf("%.4lf\n",ans);}return 0;}