zoukankan      html  css  js  c++  java
  • hdu 2215 & hdu 3932(最小覆盖圆)

    Maple trees

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1847    Accepted Submission(s): 574


    Problem Description
    There are a lot of trees in HDU. Kiki want to surround all the trees with the minimal required length of the rope . As follow,

    To make this problem more simple, consider all the trees are circles in a plate. The diameter of all the trees are the same (the diameter of a tree is 1 unit). Kiki can calculate the minimal length of the rope , because it's so easy for this smart girl.
    But we don't have a rope to surround the trees. Instead, we only have some circle rings of different radius. Now I want to know the minimal required radius of the circle ring. And I don't want to ask her this problem, because she is busy preparing for the examination.
    As a smart ACMer, can you help me ?
     
    Input
    The input contains one or more data sets. At first line of each input data set is number of trees in this data set n (1 <= n <= 100), it is followed by n coordinates of the trees. Each coordinate is a pair of integers, and each integer is in [-1000, 1000], it means the position of a tree’s center. Each pair is separated by blank.
    Zero at line for number of trees terminates the input for your program.
     
    Output
    Minimal required radius of the circle ring I have to choose. The precision should be 10^-2.
     
    Sample Input
    2 1 0 -1 0 0
     
    Sample Output
    1.50
     
    题意:求将所有树包括进来的最小圆的半径,最后要加上树本身的半径(树的直径为1).
    最小圆覆盖问题:
    一.概念引入
    最小包围圆问题:对于给定的平面上甩个点所组成的一个集合P,求出P的最小包围圆,即包含P中所有点、半径最小
    的那个圆。也就是求出这个最小包围圆的圆心位置和半径。
    
    下面是若干性质。
    
    1.有限点集P的最小包围圆是唯一的。这里约定,若P中只有一个点v,则最小包围圆是退化的,其半径为0,圆心为点v。
    2.非退化最小包围圆可以由2个或者3个边界点定义。边界上只有两个点,则必定是直径两端,其它点都在圆内部。
    3.点集P中,距离最大的2个点A、B不一定都在边界上,但是必有d≥|AB|。
    4.直角三角形或钝角三角形的3个顶点的最小包围圆是以最长边为直径的圆;锐角三角形3个顶点的最小包围圆是三角形
    的外接圆。
    5.新加入点一定在圆上。
    以上资料参考:http://www.cnblogs.com/hxsyl/p/3226562.html
     hdu 2215
    ///最小圆覆盖问题:
    /**一.概念引入
    最小包围圆问题:对于给定的平面上甩个点所组成的一个集合P,求出P的最小包围圆,即包含P中所有点、半径最小
    的那个圆。也就是求出这个最小包围圆的圆心位置和半径。
    
    下面是若干性质。
    
    1.有限点集P的最小包围圆是唯一的。这里约定,若P中只有一个点v,则最小包围圆是退化的,其半径为0,圆心为点v。
    2.非退化最小包围圆可以由2个或者3个边界点定义。边界上只有两个点,则必定是直径两端,其它点都在圆内部。
    3.点集P中,距离最大的2个点A、B不一定都在边界上,但是必有d≥|AB|。
    4.直角三角形或钝角三角形的3个顶点的最小包围圆是以最长边为直径的圆;锐角三角形3个顶点的最小包围圆是三角形
    的外接圆。
    5.新加入点一定在圆上。
    */
    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    using namespace std;
    const int N = 105;
    const double eps = 1e-8;
    
    struct Point{
        double x,y;
    }p[N];
    
    Point c; ///这是最小圆的圆心
    double r; ///这是最小圆半径
    int n;
    
    double dis(Point a,Point b){
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    /**计算外接圆的圆心*/
    Point circumcenter(Point a,Point b,Point c){
        Point ret=a;
        double a1 = (b.x-a.x),b1=(b.y-a.y),c1 = (a1*a1+b1*b1)/2;
        double a2 = (c.x-a.x),b2=(c.y-a.y),c2 = (a2*a2+b2*b2)/2;
        double d=a1*b2-a2*b1;
        ret.x+=(c1*b2-c2*b1)/d;
        ret.y+=(a1*c2-a2*c1)/d;
        return ret;
    
    }
    void min_cover_circle(){
        //random_shuffle(p,p+n); ///模板上面的这个函数是打乱点,这个题不要比要还快15MS
        c = p[0],r = 0;
        for(int i=1;i<n;i++){ ///i是第一个点
            if(dis(p[i],c)-r>eps){
                c = p[i],r=0;
                for(int j=0;j<i;j++){ ///j是第二个点
                    if(dis(p[j],c)-r>eps){
                       c.x = (p[i].x+p[j].x)/2;
                       c.y = (p[i].y+p[j].y)/2;
                       r = dis(p[j],c);
                       for(int k=0;k<j;k++){ ///k是第三个点
                            if(dis(p[k],c)-r>eps){
                                c = circumcenter(p[i],p[j],p[k]);
                                r = dis(p[i],c);
                            }
                       }
                    }
                }
            }
        }
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF&&n){
            for(int i=0;i<n;i++){
                scanf("%lf%lf",&p[i].x,&p[i].y);
            }
            min_cover_circle();
            printf("%.2lf
    ",r+0.5);
        }
        return 0;
    }

     hdu 3932

    ///最小圆覆盖问题:
    /**一.概念引入
    最小包围圆问题:对于给定的平面上甩个点所组成的一个集合P,求出P的最小包围圆,即包含P中所有点、半径最小
    的那个圆。也就是求出这个最小包围圆的圆心位置和半径。
    
    下面是若干性质。
    
    1.有限点集P的最小包围圆是唯一的。这里约定,若P中只有一个点v,则最小包围圆是退化的,其半径为0,圆心为点v。
    2.非退化最小包围圆可以由2个或者3个边界点定义。边界上只有两个点,则必定是直径两端,其它点都在圆内部。
    3.点集P中,距离最大的2个点A、B不一定都在边界上,但是必有d≥|AB|。
    4.直角三角形或钝角三角形的3个顶点的最小包围圆是以最长边为直径的圆;锐角三角形3个顶点的最小包围圆是三角形
    的外接圆。
    5.新加入点一定在圆上。
    */
    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    using namespace std;
    const int N = 1005;
    const double eps = 1e-8;
    
    struct Point{
        double x,y;
    }p[N];
    
    Point c; ///这是最小圆的圆心
    double r; ///这是最小圆半径
    int n;
    
    double dis(Point a,Point b){
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    /**计算外接圆的圆心*/
    Point circumcenter(Point a,Point b,Point c){
        Point ret=a;
        double a1 = (b.x-a.x),b1=(b.y-a.y),c1 = (a1*a1+b1*b1)/2;
        double a2 = (c.x-a.x),b2=(c.y-a.y),c2 = (a2*a2+b2*b2)/2;
        double d=a1*b2-a2*b1;
        ret.x+=(c1*b2-c2*b1)/d;
        ret.y+=(a1*c2-a2*c1)/d;
        return ret;
    
    }
    void min_cover_circle(){
        //random_shuffle(p,p+n); ///模板上面的这个函数是打乱点,这个题不要比要还快15MS
        c = p[0],r = 0;
        for(int i=1;i<n;i++){ ///i是第一个点
            if(dis(p[i],c)-r>eps){
                c = p[i],r=0;
                for(int j=0;j<i;j++){ ///j是第二个点
                    if(dis(p[j],c)-r>eps){
                       c.x = (p[i].x+p[j].x)/2;
                       c.y = (p[i].y+p[j].y)/2;
                       r = dis(p[j],c);
                       for(int k=0;k<j;k++){ ///k是第三个点
                            if(dis(p[k],c)-r>eps){
                                c = circumcenter(p[i],p[j],p[k]);
                                r = dis(p[i],c);
                            }
                       }
                    }
                }
            }
        }
    }
    int main()
    {
        int X,Y;
        while(scanf("%d%d%d",&X,&Y,&n)!=EOF){
            for(int i=0;i<n;i++){
                scanf("%lf%lf",&p[i].x,&p[i].y);
            }
            min_cover_circle();
            printf("(%.1lf,%.1lf).
    %.1lf
    ",c.x,c.y,r);
        }
        return 0;
    }
  • 相关阅读:
    微软RPC技术学习小结
    [COM Interop学习小结]实现一个C#调用C++的示例
    [一个小问题]Mainfest配置文件的version问题小结
    【小结】IIS7下的Http Native Module开发
    Active Sync与IIS7 Classic&Integrated模式,Exchange 2007&2010的关系
    是否能在构造函数,析构函数中抛出异常?
    Trouble Shooting的一些感想(实时补充)
    python中 try、except、finally 的执行顺序
    Hessian怎样实现远程调用
    mysql的三种驱动类型
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5440184.html
Copyright © 2011-2022 走看看