Geometry Problem HDU - 6242(随机化,覆盖圆)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leekerian/article/details/89236822
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <ctime>
using namespace std;


const double eps=1e-8;
int sgn(double x)
{
    if(fabs(x)<eps) return 0;
    if(x<0) return -1;
    else return 1;
}

struct point{
    double x,y;
    point(){}
    point(double _x,double _y)
    {
        x=_x;
        y=_y;
    }
    point operator -(const point &b)const
    {
        return point(x-b.x,y-b.y);
    }
    double operator *(const point &b)const 
    {
        return x*b.x+y*b.y;
    }
    point operator /(const double &k)const{
        return point(x/k,y/k);
    }
    double distance(point p){
        return hypot(x - p.x,y - p.y);
    }
    double len(){
        return hypot(x,y);//库函数
    }
    point trunc(double r){
        double l = len();
        if(!sgn(l))return *this;
        r /= l;
        return point(x*r,y*r);
    }
    double operator ^(const point &b)const{
        return x*b.y-y*b.x;
    }
    point operator +(const point &b)const{
        return point(x+b.x,y+b.y);
    }
    point rotleft(){
        return point( - y,x);
    }
    point rotright(){
        return point(y, - x);
    }
};

point p[111111];
struct Line{
    point s,e;
    Line(){}
    Line(point _s,point _e){
    s = _s;
    e = _e;
    }
    point crosspoint(Line v){
        double a1 = (v.e - v.s)^(s - v.s);
        double a2 = (v.e - v.s)^(e - v.s);
        return point((s.x*a2 - e.x*a1)/(a2 - a1),(s.y*a2 - e.y*a1)/(a2 - a1));
    }
};

struct circle{
    point p;//圆心
    double r;//半径
    circle(){}
    circle(point _p,double _r){
        p = _p;
        r = _r;
    }
    circle(double x,double y,double _r){
        p = point(x,y);
        r = _r;
    }
    //三角形的外接圆
    //需要 Point 的 + / rotate() 以及 Line 的 crosspoint()
    //利用两条边的中垂线得到圆心
    //测试:UVA12304
    circle(point a,point b,point c){
        Line u = Line((a+b)/2,((a+b)/2)+((b - a).rotleft()));
        Line v = Line((b+c)/2,((b+c)/2)+((c - b).rotleft()));
        p = u.crosspoint(v);
        r = p.distance(a);
    }
    int relation(point b){
        double dst = b.distance(p);
        if(sgn(dst - r) < 0)return 2;
        else if(sgn(dst - r)==0)return 1;
        return 0;
    }

};

int main()
{
    srand(time(0));
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        if(n==1)
            printf("%lf %lf %lf\n",p[0].x+1,p[0].y,1.0);
        else if(n<=4&&n>1)
            printf("%lf %lf %lf\n",(p[0].x+p[1].x)/2,(p[0].y+p[1].y)/2,p[0].distance(p[1])/2);
        else
        {
            circle c1;
            while(1)
            {
                int a=rand()%n;
                int b=rand()%n;
                int c=rand()%n;
                if(a==b||b==c||a==c) continue;
                if(sgn((p[b]-p[a])^(p[c]-p[a]))==0) continue;
                c1=circle(p[a],p[b],p[c]);
                int sum=0;
                for(int i=0;i<n;i++)
                {
                    
                    if(c1.relation(p[i])==1)
                        sum++;
                }   
                if(sum>=(n+1)/2)
                    break;
            }   
            printf("%lf %lf %lf\n",c1.p.x,c1.p.y,c1.r);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/leekerian/article/details/89236822