//就是找一个圆(圆心为给出的圆中的一个),满足覆盖其他所有的圆至少一般的面积
#include<stdio.h>
#include<math.h>
#define INF 100000000
#define EPS 1e-8
#define PI 3.1415926
struct 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;
else
left=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;
}
杭电 3264(相交圆求面积模板)
最新推荐文章于 2018-02-25 14:17:21 发布