枚举每个点当圆心,用二分枚举半径,
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const double PI=3.141592653;
const double eps=1e-7;
struct point
{
double x;
double y;
double r;
};
point node[55];
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 GetArea(point a,point b) //求两个圆的相交面积,上题的模版函数,
{
double d=dis(a,b);
if(d>=a.r+b.r) return 0;
double r=(a.r>b.r?b.r:a.r);
if( d<=fabs(a.r-b.r) ) return PI*r*r;
double A1=acos( (a.r*a.r+d*d-b.r*b.r)/2/a.r/d );
double A2=acos( (b.r*b.r+d*d-a.r*a.r)/2/b.r/d );
double res=A1*a.r*a.r + A2*b.r*b.r;
res-=sin(A1)*a.r*d;
return res;
}
bool ok(double r,int now)
{
point a;
a.r=r; a.x=node[now].x; a.y=node[now].y;
for(int i=0;i<n;i++)
{
//if(i==now) continue;
if(GetArea(node[i],a) < (PI*node[i].r*node[i].r)/2 )
return false;
}
return true;
}
double Get_R(int i)
{
double l=0,r=50000,mid; //二分,eps来控制精度。
while(l+eps<=r)
{
mid=(l+r)/2;
if(ok(mid,i)) r=mid;
else l=mid;
}
return mid;
}
int main()
{
int ncase,i;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%lf%lf%lf",&node[i].x,&node[i].y,&node[i].r);
double res=99999999.0;
for(i=0;i<n;i++)
{
double tt=Get_R(i);
if(res>tt) res=tt;
}
printf("%.4lf\n",res);
}
return 0;
}