hdu 3264 Open-air shopping malls 计算几何

计算几何入门不久,大家相互学习探讨!

题意:

    给定N个互不相交的圆,告诉圆心的坐标和半径,求一个圆的半径,要求这个圆的圆心与N个圆中的某一个的圆心重合,并且这个圆至少要覆盖每个圆的一半,求满足条件的最小半径。

思路(baudu+小结):

  既然圆心是某个圆的圆心,那么我们可以枚举圆心,只是半径怎么求呢?我们可以用二分的思想找到半径,依次求出每个圆心上满足条件的圆的半径,再取一个min值即为所求。

  两圆相离、外切、内切、内含都好断定,然则相交情况如何断定面积,参考网址http://www.cnblogs.com/evan-oi/archive/2012/03/14/2395989.html

#include<stdio.h>
#include<math.h>
const double eps = 1e-8;
const double pi = acos(-1.0);
struct Point
{
    double x,y;
};
struct circle
{
    Point pp;
    double r;
}cir[30];
double area[30];
int n;
double cir_area_inst(Point c1,double r1,Point c2,double r2)
{  //两圆面积交
    double a1, a2, d, ret;
    d = sqrt((c1.x-c2.x)*(c1.x-c2.x)+(c1.y-c2.y)*(c1.y-c2.y));
    //圆心距离
    if ( d > r1 + r2 - eps )
        return 0;            //相离
    if ( d < r2 - r1 + eps )
        return pi*r1*r1;   //内切与包含
    if ( d < r1 - r2 + eps )
        return pi*r2*r2;   //内切与包含
    a1 = acos((r1*r1+d*d-r2*r2)/2/d/r1);//相交
    //余弦定理求角
    a2 = acos((r2*r2+d*d-r1*r1)/2/d/r2);
    ret = (a1-0.5*sin(2*a1))*r1*r1 + (a2-0.5*sin(2*a2))*r2*r2;
    //求楔形(扇形减三角形)面积
    return ret;

}
bool judge(Point p,double r)//枚举每个圆心
{
    int i,j;
    for(i=0;i<n;i++)
    {
        double Are = cir_area_inst(p,r,cir[i].pp,cir[i].r);
        if(Are<area[i])return false;
    }
    return true;
}
int main()
{
    int t,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            scanf("%lf %lf %lf",&cir[i].pp.x,&cir[i].pp.y,&cir[i].r);
            area[i] = pi*cir[i].r*cir[i].r/2;
        }
        Point a;
    double rans = 200000;  //初始化符合要求的大圆半径
    for(i=0;i<n;i++)
    {
        a = cir[i].pp;
        double l=0,r=200000,mid;
        while(fabs(l-r)>eps)//二分法
        {
            mid = (l+r)/2;
            if(judge(a,mid))
            {
                r =mid;
                if(mid<rans)//找符合要求的最小的圆
                rans =mid;
            }
            else l=mid;
        }
    }
    printf("%.4lf\n",rans);
    }
    return 0;
}

 

做一道题,各种找代码+详解,然后才弄懂啊!!!

转载于:https://www.cnblogs.com/XDJjy/archive/2013/04/02/2995918.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值