CF333E 题解
这题很有技巧。
首先是求最大的圆的半径,因为这里没有边界,所以圆的半径只与三个点间的距离相关,用心想想当两个圆相切时半径肯定最大,而三点间有三个距离,我们肯定取最小的。
然后就是哪三个点,看到
我们将每两个点间的距离预处理,然后从大到小枚举,每次将两个点互相连边,在枚举到一条边时就只需要判断之前有没有一个点同时与这两个点连边,这东西我们维护一个 bitset 来优化一个
总时间复杂度
code
#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int N=3001;
struct Node{
int x, y;
inline int get_long(const Node &p)const{return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);}
}a[3005];
struct node{
int x, y, z;
inline bool operator<(const node &p)const{return z > p.z;}
};
vector<node> vec;
int n;
bitset<3005> edge[3005],tmp;
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d%d", &a[i].x, &a[i].y);
for(int j = i - 1; j; j--){
vec.push_back(node{i, j, a[i].get_long(a[j])});
}
}
stable_sort(vec.begin(), vec.end());
for(auto &p: vec) {
edge[p.x][p.y] = 1, edge[p.y][p.x] = 1;
if((edge[p.x]&edge[p.y]).any()) {
printf("%.20lf", sqrt(p.z) / 2.0);
return 0;
}
}
return 0;
}