题目描述

给出N个点,让你画一个最小的包含所有点的圆。

输入格式

先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000.0)

输出格式

输出圆的半径,及圆心的坐标,保留10位小数

输入输出样例

输入 #1复制

6
8.0 9.0
4.0 7.5
1.0 2.0
5.1 8.7
9.0 2.0
4.5 1.0

输出 #1复制

5.0000000000
5.0000000000 5.0000000000

说明/提示

5.00 5.00 5.0

 

#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
const int N = 1e5 + 5;

struct node
{
    double x, y;
}p[N];

node c; ///圆心
double r;   ///半径

int sgn(double x)
{
    if (fabs(x) < eps)
        return 0;
    else
        return x < 0 ? -1 : 1;
}

double Distance(node A, node B) ///两点距离
{
    return hypot(A.x - B.x, A.y - B.y); ///hypot(a, b)求以a, b为直角边的直角三角形斜边长
}

///求三角形abc的外接圆圆心
node circle_center(const node a, const node b, const node c)
{
    node center;
    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;
    center.x = a.x + (c1 * b2 - c2 * b1) / d;
    center.y = a.y + (a1 * c2 - a2 * c1) / d;
    return center;
}

///求最小圆覆盖,返回圆心c和半径r:
void min_cover_circle(int n)
{
    random_shuffle(p, p + n);             ///打乱所有点
    c = p[0];
    r = 0;                    ///第一个点
    for (int i = 1; i < n; ++i)        ///剩下所有点
    {
        if (sgn(Distance(p[i], c) - r) > 0) ///pi在圆外部
        {
            c = p[i];
            r = 0;                ///将圆心设为pi半径为0
            for (int j = 0; j < i; ++j) ///重新检查前面的点
            {
                if (sgn(Distance(p[j], c) - r) > 0)///两点定圆
                {
                    c.x = (p[i].x + p[j].x) / 2;
                    c.y = (p[i].y + p[j].y) / 2;
                    r = Distance(p[j], c);
                    for (int k = 0; k < j; ++k)
                    {
                        if (sgn(Distance(p[k], c) - r) > 0)
                        {
                            c = circle_center(p[i], p[j], p[k]);
                            r = Distance(p[i], c);
                        }
                    }
                }
            }
        }
    }
}

int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        for(int i = 0; i < n; ++i)
        {
            scanf("%lf%lf", &p[i].x, &p[i].y);
        }
        min_cover_circle(n);
        printf("%.10f\n", r);
        printf("%.10f %.10f\n", c.x, c.y);
    }
    return 0;
}