zoukankan      html  css  js  c++  java
  • hdu 3264 Openair 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;
    }

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

  • 相关阅读:
    habse与Hadoop兼容性问题
    java读取TXT文件(硬核区分编码格式)
    ffmpeg相关用法
    java服务器间http通讯,同时传输文件流和数据,并接收返回的文件流或数据
    js 获取正整数各个位上的数字
    解决Input输入中文重复出现拼音
    为什么 io 包一般以 byte 数组做为处理单位?
    Vue3 + Ts 封装axios
    Vue3 ant design 使用Moment.js日期格式化的实现
    Vue3 NProgress进度条
  • 原文地址:https://www.cnblogs.com/XDJjy/p/2995918.html
Copyright © 2011-2022 走看看