[模板] 最小圆覆盖 求三角形外心 ZOJ-1450
利用随机函数把理论复杂度降到n
代码
struct Point {
double x, y;
};
Point p[500005];
Point o;
int n;
double ri;
double dis(Point a, Point b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
void tt(Point p1, Point p2, Point p3) {
double a, b, c, d, e, f;
a = p2.y - p1.y;
b = p3.y - p1.y;
c = p2.x - p1.x;
d = p3.x - p1.x;
f = p3.x * p3.x + p3.y * p3.y - p1.x * p1.x - p1.y * p1.y;
e = p2.x * p2.x + p2.y * p2.y - p1.x * p1.x - p1.y * p1.y;
o.x = (a * f - b * e) / (2 * a * d - 2 * b * c);
o.y = (d * e - c * f) / (2 * a * d - 2 * b * c);
ri = dis(o, p1);
}
int main() {
while (scanf("%d", &n), n) {
for (int i = 1; i <= n; i++) scanf("%lf%lf", &p[i].x, &p[i].y);
random_shuffle(p + 1, p + 1 + n);
o = p[1];
ri = 0;
for (int i = 2; i <= n; i++) {
if (dis(p[i], o) > ri + eps) {
o = p[i], ri = 0;
for (int j = 1; j <= i - 1; j++) {
if (dis(o, p[j]) > ri + eps) {
o.x = (p[i].x + p[j].x) / 2;
o.y = (p[i].y + p[j].y) / 2;
ri = dis(o, p[j]);
for (int k = 1; k <= j - 1; k++)
if (dis(o, p[k]) > ri + eps) tt(p[i], p[j], p[k]);
}
}
}
}
printf("%.2f %.2f %.2f\n", o.x, o.y, ri);
}
}