在排除商店的中心不在雨伞范围内,排除伞在商店内而面积达不到一半时。
面雨伞覆盖了整个商店是可行的,最后剩一种相交的情况,求圆面积的并。
//之前不怎么敢用三角函数怕丢失精度,没想是可以的。
代码如下 :
#include<iostream>
#include<cstdio>
#include<math.h>
#define eps 1e-8
#define inf 1e8
#define maxn 100
#define PI acos(-1.0)
struct point {double x,y;};
struct circle{point cen;double r;}cir[maxn];
int id;double minr;
int n;
bool zero(double x){return x>0? x<eps :x>-eps;}
double min(double a,double b){return a>b? b:a;}
double distance(point p1,point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
bool judge(double rr)
{
int i;
for(i=0;i<n;i++)
{
double dis=distance(cir[id].cen,cir[i].cen);
if(rr-dis< eps)return false;//
if(rr-dis-cir[i].r>=0)continue;//c?úo?,?ú?Da
double a=cir[i].r*cir[i].r*PI;
double c=rr*rr*PI;
if(dis+rr-cir[i].r<-eps)//a?úo?c
{
if(c-a/2> -eps)continue;
else return false;
}
double l=(rr+dis+cir[i].r)/2;
double area1=2*sqrt(l*(l-rr)*(l-dis)*(l-cir[i].r));
double anga=acos((cir[i].r*cir[i].r+dis*dis-rr*rr)/(2*dis*cir[i].r));
double angc=acos((dis*dis+rr*rr-cir[i].r*cir[i].r)/(2*dis*rr));
double res=anga/(PI)*a+angc/(PI)*c-area1;
if(res-a/2<0)return false;
}
return true;
}
double two(double l,double r)
{
double mid=(l+r)/2.0;
if(zero(r-l))return mid;
if(judge(mid))
return two(l,mid);
else return two(mid,r);
}
int main()
{
int t ;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int i;
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf",&cir[i].cen.x,&cir[i].cen.y,&cir[i].r);
}
double minn=inf;
for(i=0;i<n;i++)
{
id=i;
minn=min(minn,two(0,inf));
}
printf("%.4lf\n",minn);
}
return 0;
}