给出N个点,从零时刻起,分别以这N个点为圆心的N个圆逐渐变大,有半径r=时刻t;随着时间推移,图形当中可能出现一些”洞”,而且出现的洞一定会在某时刻消失。严格地,一个洞被定义为封闭的、连通的未被圆覆盖的区域,可以理解为被圆所围起来的区域。对于给出的n个点,求出最后一个洞消失的时间;如果没有出现过洞,输出-1。
最后一个洞♂
考虑3个圆的情况,发现洞消失的位置即三个圆心围成的三角形的外心,而且当且仅当三角形是锐角三角形的时候才会存在洞。
要不然就是正方形的中心。、
因为坐标是整数,所以不会出现正五边形以上的,所以情况就这2种。
因此我们可以枚举所有的三角形和正方形,进而枚举所有可能的洞。
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 105;
#define FOR(i,j,k) for(int i=j;i<=k;++i)
double sqr(double d) { return d * d; }
bool deql(double a, double b)
{ return fabs(a - b) < 1e-10; }
bool triangle(double a, double b, double c)
{ return a * a + b * b >= c * c; }
bool square(double a, double b, double c)
{ return deql(a * a + b * b, c * c) && deql(a, b); }
struct Point {
double x, y;
Point(double a = 0, double b = 0): x(a), y(b) { }
bool operator== (const Point &b) const {
return x == b.x && y == b.y;
}
} pt[N];
double dis(const Point &a, const Point &b) {
return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
}
Point *circumcenter(const Point &x, const Point &y, const Point &z) {
static Point p;
double A2, B2, A1, B1, C2, C1, d, d1, d2;
A1 = 2 * (y.x - x.x); B1 = 2 * (y.y - x.y);
C1 = sqr(y.x) - sqr(x.x) + sqr(y.y) - sqr(x.y);
A2 = 2 * (z.x - y.x); B2 = 2 * (z.y - y.y);
C2 = sqr(z.x) - sqr(y.x) + sqr(z.y) - sqr(y.y);
d = A1 * B2 - B1 * A2;
d1 = C1 * B2 - B1 * C2;
d2 = A1 * C2 - C1 * A2;
if (d == 0.0) return 0;
return &(p = Point(d1 / d, d2 / d));
}
int n;
double getmin(Point x) {
double r = 1e9;
FOR(i,1,n) r = min(r, dis(pt[i], x));
return r;
}
int main() {
Point c, w, *tmp; double ans = -1;
scanf("%d", &n);
FOR(i,1,n) scanf("%lf%lf", &pt[i].x, &pt[i].y);
FOR(i,1,n) FOR(j,i+1,n) FOR(k,j+1,n) {
Point x = pt[i], y = pt[j], z = pt[k];
double a = dis(y, z), b = dis(x, y), c = dis(x, z), d;
if (square(b, c, a)) swap(c, a), swap(x, y);
if (square(a, c, b)) swap(c, b), swap(y, z);
if (square(a, b, c)) {
c = Point((x.x + z.x) / 2, (x.y + z.y) / 2);
w = Point(c.x * 2 - y.x, c.y * 2 - y.y);
FOR(l,1,n) if (pt[l] == w) {
double t = getmin(c);
if (t * 2 > a && ans < t) ans = t;
break;
}
}
tmp = circumcenter(x, y, z);
if (!tmp) continue;
if (!triangle(a, b, c) || !triangle(a, c, b) || !triangle(b, c, a)) continue;
double mx = max(a, max(b, c)), t = getmin(*tmp);
if (t * 2 > mx && ans < t) ans = t;
}
if (ans < 0) puts("-1");
else printf("%.9lf", ans);
return 0;
}