zoukankan      html  css  js  c++  java
  • ZOJ1450 BZOJ1136 BZOJ1137 HDU3932[最小圆覆盖]

    Minimal Circle

    Time Limit: 5 Seconds      Memory Limit: 32768 KB

    You are to write a program to find a circle which covers a set of points and has the minimal area. There will be no more than 100 points in one problem.


    Input

    The input contains several problems. The first line of each problem is a line containing only one integer N which indicates the number of points to be covered. The next N lines contain N points. Each point is represented by x and y coordinates separated by a space. After the last problem, there will be a line contains only a zero.


    Output

    For each input problem, you should give a one-line answer which contains three numbers separated by spaces. The first two numbers indicate the x and y coordinates of the result circle, and the third number is the radius of the circle. (use escape sequence %.2f)


    Sample Input

    2
    0.0 0.0
    3 0
    5
    0 0
    0 1
    1 0
    1 1
    2 2
    0


    Sample Output

    1.50 0.00 1.50
    1.00 1.00 1.41


    Source: Asia 1997, Shanghai (Mainland China)


    裸题哦

    注意求重心的方法

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const int N=2005;
    const double INF=1e9;
    const double eps=1e-8;
    const double pi=acos(-1);
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    
    inline int sgn(double x){
        if(abs(x)<eps) return 0;
        else return x<0?-1:1;
    }
    
    struct Vector{
        double x,y;
        Vector(double a=0,double b=0):x(a),y(b){}
        bool operator <(const Vector &a)const{
            return sgn(x-a.x)<0||(sgn(x-a.x)==0&&sgn(y-a.y)<0);
        }
        void print(){printf("%lf %lf
    ",x,y);}
    };
    typedef Vector Point;
    Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
    Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
    Vector operator *(Vector a,double b){return Vector(a.x*b,a.y*b);}
    Vector operator /(Vector a,double b){return Vector(a.x/b,a.y/b);}
    bool operator ==(Vector a,Vector b){return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;}
    double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}
    double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
    double Len(Vector a){return sqrt(Dot(a,a));}
    Vector Normal(Vector a){
        return Vector(-a.y,a.x);//counterClockwise
    };
    struct Line{
        Point s,t;
        Line(){}
        Line(Point a,Point b):s(a),t(b){}
    };
    bool isLSI(Line l1,Line l2){
        Vector v=l1.t-l1.s,u=l2.s-l1.s,w=l2.t-l1.s;
        return sgn(Cross(v,u))!=sgn(Cross(v,w));
    }
    Point LI(Line a,Line b){
        Vector v=a.s-b.s,v1=a.t-a.s,v2=b.t-b.s;
        double t=Cross(v2,v)/Cross(v1,v2);
        return a.s+v1*t;
    }
    Point Circumcenter(Point a,Point b,Point c){
        Point p=(a+b)/2,q=(a+c)/2;
        Vector v=Normal(b-a),u=Normal(c-a);
        if(sgn(Cross(v,u))==0){
            if(sgn(Len(a-b)+Len(b-c)-Len(a-c))==0) return (a+c)/2;
            if(sgn(Len(a-b)+Len(a-c)-Len(b-c))==0) return (b+c)/2;
            if(sgn(Len(a-c)+Len(b-c)-Len(a-b))==0) return (a+b)/2;
        }
        return LI(Line(p,p+v),Line(q,q+u));
    }
    
    double minCircleCover(Point p[],int n,Point &c){
        random_shuffle(p+1,p+1+n);
        c=p[1];
        double r=0;
        for(int i=2;i<=n;i++)
            if(sgn(Len(c-p[i])-r)>0){
                c=p[i],r=0;
                for(int j=1;j<i;j++)
                    if(sgn(Len(c-p[j])-r)>0){
                        c=(p[i]+p[j])/2,r=Len(c-p[i]);
                        for(int k=1;k<j;k++)
                            if(sgn(Len(c-p[k])-r)>0){
                                c=Circumcenter(p[i],p[j],p[k]);
                                r=Len(c-p[i]);
                            }
                    }
            }
        return r;
    }
    
    int n;
    Point p[N],c;
    int main(int argc, const char * argv[]){
        while(true){
            n=read();if(n==0) break;
            for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
            double r=minCircleCover(p,n,c);
            printf("%.2f %.2f %.2f
    ",c.x,c.y,r);
        }
    }

     HDU3932好像还有模拟退火做法

  • 相关阅读:
    孙权用人之道:“六力”兼备
    JDK 自带工具试用(一)
    Apache ab 测试工具使用(一)
    Amoeba详细介绍
    TCP/IP 标志位 SYN ACK RST UTG PSH FIN
    ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'
    jsp 中声明方法的使用
    Java遍历一个文件夹下的全部文件
    WAMP 2.5 &quot;FORBIDDEN&quot; error
    LeetCode总结--二分查找篇
  • 原文地址:https://www.cnblogs.com/candy99/p/6359197.html
Copyright © 2011-2022 走看看