Init
This commit is contained in:
92
Luogu-P2533.cpp
Normal file
92
Luogu-P2533.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <random>
|
||||
const double EPS = 1e-7;
|
||||
struct point {
|
||||
double x, y;
|
||||
inline point operator+(point rhs) const {
|
||||
return (point){x + rhs.x, y + rhs.y};
|
||||
}
|
||||
inline point operator-(point rhs) const {
|
||||
return (point){x - rhs.x, y - rhs.y};
|
||||
}
|
||||
inline point operator*(double rhs) const { return (point){x * rhs, y * rhs}; }
|
||||
inline double len() const { return sqrt(x * x + y * y); }
|
||||
};
|
||||
inline int sgn(double x) {
|
||||
if (x < -EPS) return -1;
|
||||
if (x > EPS) return 1;
|
||||
return 0;
|
||||
}
|
||||
inline double det(point x, point y) { return x.x * y.y - x.y * y.x; }
|
||||
inline double dot(point x, point y) { return x.x * y.x + x.y * y.y; }
|
||||
inline double dis(point x, point y) { return (x - y).len(); }
|
||||
struct circle {
|
||||
point c;
|
||||
double r;
|
||||
};
|
||||
inline bool in_circle(point p, circle c) {
|
||||
return sgn(c.r - (c.c - p).len()) >= 0;
|
||||
}
|
||||
inline circle make_circle(point x, point y) {
|
||||
return (circle){(x + y) * 0.5, (x - y).len() * 0.5};
|
||||
}
|
||||
inline circle make_circle(point x, point y, point z) {
|
||||
point p = y - x, q = z - x, s = (point){dot(p, p) * 0.5, dot(q, q) * 0.5};
|
||||
double d = 1.0 / det(p, q);
|
||||
p = (point){det(s, (point){p.y, q.y}), det((point){p.x, q.x}, s)} * d;
|
||||
return (circle){x + p, p.len()};
|
||||
}
|
||||
inline circle get_circle(point x, point y, point z) {
|
||||
if (sgn(det(y - x, z - x)) == 0) {
|
||||
if ((x - y).len() >= (x - z).len()) {
|
||||
if ((x - y).len() >= (y - z).len())
|
||||
return make_circle(x, y);
|
||||
else
|
||||
return make_circle(y, z);
|
||||
} else {
|
||||
if ((x - z).len() >= (y - z).len())
|
||||
return make_circle(x, z);
|
||||
else
|
||||
return make_circle(y, z);
|
||||
}
|
||||
} else
|
||||
return make_circle(x, y, z);
|
||||
}
|
||||
using namespace std;
|
||||
const int maxn = 1e6 + 10;
|
||||
mt19937 rnd(random_device{}());
|
||||
inline int rand_less(int n) { return rnd() % n; }
|
||||
int n;
|
||||
point pnt[maxn];
|
||||
int main() {
|
||||
#ifdef local
|
||||
freopen("pro.in", "r", stdin);
|
||||
#endif
|
||||
scanf("%d", &n);
|
||||
for (int i = 1; i <= n; i++) scanf("%lf%lf", &pnt[i].x, &pnt[i].y);
|
||||
if (n == 2) {
|
||||
printf("%.2lf %.2lf %.2lf\n", ((pnt[1] + pnt[2]) * 0.5).x,
|
||||
((pnt[1] + pnt[2]) * 0.5).x, dis(pnt[1], pnt[2]) / 2);
|
||||
return 0;
|
||||
}
|
||||
random_shuffle(pnt + 1, pnt + 1 + n, rand_less);
|
||||
circle cc = {pnt[1], 0};
|
||||
// 注意:此处不要自作聪明地初始化,必须保证一定是真正的最小圆覆盖
|
||||
for (int i = 2; i <= n; i++) {
|
||||
if (in_circle(pnt[i], cc)) continue;
|
||||
cc = make_circle(pnt[i], pnt[1]);
|
||||
for (int j = 2; j <= i - 1; j++) {
|
||||
if (in_circle(pnt[j], cc)) continue;
|
||||
cc = make_circle(pnt[j], pnt[i]);
|
||||
for (int k = 1; k <= j - 1; k++) {
|
||||
if (in_circle(pnt[k], cc)) continue;
|
||||
cc = get_circle(pnt[k], pnt[j], pnt[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%.2lf %.2lf %.2lf\n", cc.c.x, cc.c.y, cc.r);
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user