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

  • 相关阅读:
    Redis哨兵(Sentinel)模式
    一个http请求就是一个线程吗,java的服务是每收到一个请求就新开一个线程来处理吗
    Redis 快速入门
    Redis 持久化之RDB和AOF
    Junit 入门使用教程 转自:http://www.cnblogs.com/ysocean/p/6889906.html
    Spring里PropertyPlaceholderConfigurer类的使用 转自:https://www.cnblogs.com/huqianliang/p/5673701.html
    Apache Commons Codec 编码/解码 (Base64/MD5/SHA1/SHA256等算法) 转自https://blog.csdn.net/hbtj_1216/article/details/52813741
    hive中时间日期函数的使用
    关于mat函数
    strip 和split
  • 原文地址:https://www.cnblogs.com/candy99/p/6359197.html
Copyright © 2011-2022 走看看