首页 > 其他 > 详细

hdu 3265 Posters

时间:2014-11-12 23:07:35      阅读:591      评论:0      收藏:0      [点我收藏+]
///给你若干个没有交集的圆,以其中一个圆的圆心为圆心做一个圆
///使得这个圆至少包含所有圆面积的一半,求这个圆最小的半径
# 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

原文:http://blog.csdn.net/lp_opai/article/details/41050913

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!