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好像还有模拟退火做法

  • 相关阅读:
    [转]SVN 乱码问题
    [转]自己做 Visual Studio 2013 代码折叠插件
    [Java]一步一步学 Web
    [转]SQL Server 结构读取
    [转][c#]注册表经验集
    [转]加密经验集 => C#
    [转]Oracle 连接dll
    《高效能程序员的修炼》读书笔记
    Blend for Visual Studio 2013
    ASP.NET中服务器控件的生命周期
  • 原文地址:https://www.cnblogs.com/candy99/p/6359197.html
Copyright © 2011-2022 走看看