# 模板 - 最小圆覆盖

#include<bits/stdc++.h>
using namespace std;

int n;
double r;

struct point {
double x, y;
} p[100005], o;

inline double sqr(double x) { return x * x; }

inline double dis(point a, point b) {
return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
}

inline bool cmp(double a, double b) { return fabs(a - b) < 1e-8; }

point geto(point a, point b, point c) {
double a1, a2, b1, b2, c1, c2;
point ans;
a1 = 2 * (b.x - a.x), b1 = 2 * (b.y - a.y),
c1 = sqr(b.x) - sqr(a.x) + sqr(b.y) - sqr(a.y);
a2 = 2 * (c.x - a.x), b2 = 2 * (c.y - a.y),
c2 = sqr(c.x) - sqr(a.x) + sqr(c.y) - sqr(a.y);
if(cmp(a1, 0)) {
ans.y = c1 / b1;
ans.x = (c2 - ans.y * b2) / a2;
} else if(cmp(b1, 0)) {
ans.x = c1 / a1;
ans.y = (c2 - ans.x * a2) / b2;
} else {
ans.x = (c2 * b1 - c1 * b2) / (a2 * b1 - a1 * b2);
ans.y = (c2 * a1 - c1 * a2) / (b2 * a1 - b1 * a2);
}
return ans;
}

int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
for(int i = 1; i <= n; i++)
swap(p[rand() % n + 1], p[rand() % n + 1]);
o = p[1];
for(int i = 1; i <= n; i++) {
if(dis(o, p[i]) < r || cmp(dis(o, p[i]), r))
continue;
o.x = (p[i].x + p[1].x) / 2;
o.y = (p[i].y + p[1].y) / 2;
r = dis(p[i], p[1]) / 2;
for(int j = 2; j < i; j++) {
if(dis(o, p[j]) < r || cmp(dis(o, p[j]), r))
continue;
o.x = (p[i].x + p[j].x) / 2;
o.y = (p[i].y + p[j].y) / 2;
r = dis(p[i], p[j]) / 2;
for(int k = 1; k < j; k++) {
if(dis(o, p[k]) < r || cmp(dis(o, p[k]), r))
continue;
o = geto(p[i], p[j], p[k]);
r = dis(o, p[i]);
}
}
}
printf("%.10f\n%.10f %.10f", r, o.x, o.y);
return 0;
}

posted @ 2019-09-13 11:21  Inko  阅读(62)  评论(0编辑  收藏