首先这个圆边上必有至少两点,打乱数组,然后利用枚举,不断重新定义圆,找出最小的圆
代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 100005;
const double eps = 1e-8;
int n;
struct Point {
double x, y;
Point() {}
Point(double x, double y) {
this->x = x;
this->y = y;
}
void read() {
scanf("%lf%lf", &x, &y);
}
} p[N];
struct Line {
Point a, b;
Line() {}
Line(Point a, Point b) {
this->a = a;
this->b = b;
}
};
typedef Point Vector;
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 p) {
return Vector(A.x * p, A.y * p);
}
Vector operator / (Vector A, double p) {
return Vector(A.x / p, A.y / p);
}
double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x;}
int dcmp(double x) {
return x < -eps ? -1 : x > eps;
}
double dis(Point a, Point b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
Vector u = P - Q;
double t = Cross(w, u) / Cross(v, w);
return P + v * t;
}
Point CircumcircleOfTriangle(Point a, Point b, Point c) {
Line u,v;
u.a.x = (a.x + b.x) / 2;
u.a.y = (a.y + b.y) / 2;
u.b.x = u.a.x + (u.a.y - a.y);
u.b.y = u.a.y - (u.a.x - a.x);
v.a.x = (a.x + c.x) / 2;
v.a.y = (a.y + c.y) / 2;
v.b.x = v.a.x + (v.a.y - a.y);
v.b.y = v.a.y - (v.a.x - a.x);
return GetLineIntersection(u.a, u.b - u.a, v.a, v.b - v.a);
}
void Mincir() {
random_shuffle(p, p + n);
Point cir = p[0]; double r = 0;
for (int i = 1; i < n; i++) {
if (dcmp(dis(cir, p[i]) - r) <= 0) continue;
cir = p[i]; r = 0;
for (int j = 0; j < i; j++) {
if(dcmp(dis(cir, p[j]) - r) <= 0) continue;
cir.x = (p[i].x + p[j].x) / 2;
cir.y = (p[i].y + p[j].y) / 2;
r = dis(cir, p[j]);
for (int k = 0; k < j; k++) {
if (dcmp(dis(cir, p[k]) - r) <= 0) continue;
cir = CircumcircleOfTriangle(p[i], p[j], p[k]);
r = dis(cir, p[k]);
}
}
}
printf("%.2f %.2f %.2f\n", cir.x, cir.y, r);
}
int main() {
while (~scanf("%d", &n) && n) {
for (int i = 0; i < n; i++)
p[i].read();
Mincir();
}
return 0;
}