简化问题首先可以发现两个点为圆心做的圆的半径一定是两点距离的一半,其次如果是三个点那么一定是距离最近的两个点的距离的一半作为半径
把所有的边从大到小排序往一个空间里放直到构建成三角形,最后放的边一定是所有三角形中的最大的最小边
代码:
#include<iostream>
#include<algorithm>
#include<bitset>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 3000;
int x[maxn + 9], y[maxn + 9];
struct ty
{
int dis;
int u, v;
};
double distance(int i, int j)
{
return ((x[i] - x[j]) * (x[i] - x[j])) + ((y[i] - y[j]) * (y[i] - y[j]));
}
bitset <maxn+9>bs[maxn+9];//表示第i个点与哪些点连成线
ty arr[maxn * maxn];
bool cmp(ty a, ty b)
{
return a.dis > b.dis;
}
int m = 1;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
scanf("%d %d", &x[i], &y[i]);
}
for (int i = 1; i <= n; i++)
{
for (int j = i + 1; j <= n; j++)
{
arr[m].u = i;
arr[m].v = j;
arr[m++].dis = distance(i, j);
}
}
sort(arr + 1, arr + m, cmp);
for (int i = 1; i < m; i++)
{
int u = arr[i].u, v = arr[i].v;
if ((bs[u] & bs[v]) != 0)//查看u和v是否连有共同的点,有则证明构成了三角形
{
printf("%.8f", (double)sqrt(arr[i].dis) / 2.0);
return 0;
}
else//标记u和v,v和u连线
{
bs[v][u] = 1;
bs[u][v] = 1;
}
}
}