///给你若干个没有交集的圆,以其中一个圆的圆心为圆心做一个圆
///使得这个圆至少包含所有圆面积的一半,求这个圆最小的半径
# include <stdio.h>
# include <algorithm>
# include <iostream>
# include <string.h>
# include <math.h>
#include <string>
using namespace std;
struct node
{
double x;
double y;
double r;
};
int t1,t2;
double rr;
const double d = 1e-10;
const double pi = acos(-1.0);
struct node a[25];
double ss;
double cal(int x1,int y1)///两圆圆心距离
{
return sqrt((a[x1].x-a[y1].x)*(a[x1].x-a[y1].x)*1.0+(a[x1].y-a[y1].y)*(a[x1].y-a[y1].y)*1.0);
}
double area(double mid)///求两圆交叉面积
{
double a = cal(t1, t2), b = rr, c = mid;
double cta1 = acos((a * a + b * b - c * c) / 2 / (a * b)),
cta2 = acos((a * a + c * c - b * b) / 2 / (a * c));
double s1 = rr*rr*cta1 - rr*rr*sin(cta1)*(a * a + b * b - c * c) / 2 / (a * b);
double s2 = mid*mid*cta2 - mid*mid*sin(cta2)*(a * a + c * c - b * b) / 2 / (a * c);
return s1 + s2;
}
double f(double m)
{
if(area(m)-ss>=1e-20)
return 1;
else
return 0;
}
int main()
{
int t,n,i,j;
double min1,max1,min2,max2,jj;
while(~scanf("%d",&t))
{
while(t--)
{
scanf("%d",&n);
for(i=0; i<n; i++)
scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].r);
if(n==1)
{
min1=sqrt(a[0].r*a[0].r*0.5);
printf("%.4lf\n",min1);
}
else
{
double lll=1000000000;
for(i=0; i<n; i++)
{
max1=-1;
double ll=-1;
for(j=0; j<n; j++)
{
if(i!=j)
{
t2=i;
t1=j;
rr=a[t1].r;
max1=cal(i,j);
min2=max1+rr;
ss=pi*rr*rr*0.5;
double l=max1;
double r=min2;
while(r-l>d)///二分面积
{
double mid=(l+r)/2;
if(f(mid)==1)
r=mid;
else
l=mid;
}
ll=max(ll,l);
}
}
lll=min(lll,ll);
}
printf("%.4lf\n",lll);
}
}
}
return 0;
}
hdu 3265 Posters
最新推荐文章于 2020-02-07 11:05:28 发布
