显然答案具有二分性,然后就是套路性对每个点化圆。
考虑无解的情况,假设分成上下左右四个区域,显然上下连通或者左右连通无解,通路左下或右上连通无解。因此考虑对于相交的两圆进行并查集合并。
然后就裸了。
参考别人代码
#includeusing namespace std; const int N = 1e3 + 10; struct Res { double x, y; void read() { scanf("%lf %lf", &x, &y); } }a[N]; int fa[N], n, X, Y; // {n + 1, 上表面} {n + 2, 下表面} {n + 3, 左表面} {n + 4, 右表面} int find(int rt) { return rt == fa[rt] ? rt : fa[rt] = find(fa[rt]); } double Dis(Res a, Res b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } bool judge(double x) { for (int i = 1; i <= n + 4; i++) { fa[i] = i; } for (int i = 1; i <= n; i++) { if (a[i].y + x > Y) { int u = find(i), v = find(n + 1); fa[u] = v; } if (a[i].y < x) { int u = find(i), v = find(n + 2); fa[u] = v; } if (a[i].x < x) { int u = find(i), v = find(n + 3); fa[u] = v; } if (a[i].x + x > X) { int u = find(i), v = find(n + 4); fa[u] = v; } for (int j = 1; j < i; j++) { if (Dis(a[i], a[j]) < 2 * x) { int u = find(i), v = find(j); fa[u] = v; } } } if ((find(n + 1) == find(n + 2)) || (find(n + 1) == find(n + 4)) || (find(n + 3) == find(n + 2)) || (find(n + 3) == find(n + 4))) { return false; } return true; } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); scanf("%d %d %d", &X, &Y, &n); for (int i = 1; i <= n; i++) { a[i].read(); } double l = 0, r = max(X, Y); for (int i = 1; i <= 100; i++) { double mid = 0.5 * (l + r); if (judge(mid)) { l = mid; } else { r = mid; } } printf("%.10fn", l); return 0; }



