hdu 3265 Posters

来源:互联网 发布:删除建立的属性列sql 编辑:程序博客网 时间:2024/05/17 03:02
///给你若干个没有交集的圆,以其中一个圆的圆心为圆心做一个圆///使得这个圆至少包含所有圆面积的一半,求这个圆最小的半径# 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;}

0 0