处理出每个点对之间的距离,把它们看成边,问题就等价于找一个三角形,使它的最短边最长。
把这些边从大到小排序,维护每个点当前能到达点集。遍历每条边时,看两个端点能到达的点集有没有交集,如果有那么交集的点就是离两个端点距离都大于当前这条边的,那么这个三角型的最短边就是当前这条边。
收获:
维护vis数组可以使用stl中的bitset做标记数组
bool型在c语言中需要占用一个字节,而实际只有0,1两个·值,有7bit的空间被浪费了。使用bitset可以比bool数组节省7/8的空间
用法:
1.
初始化:bitset<标记数组大小> 数组名称(初始值,二进制的比如0xffff)
默认所有位都是0
any():有一位为1就返回1
none():所有位都为0返回1
count():返回1的个数
set(n):第n位置1
set():全部置1
reset(n):第n位置0
reset():所有位置0
两个bitset交集:
bitset <3> a,b,c;
c=a&b;
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define LL long long
#include <bitset>
#include <cmath>
struct node{
LL len;
int s,t;
}G[4500010];
struct point{
LL x,y;
}P[3005];
int N;
bool cmp(node a,node b){
return a.len>b.len;
}
bitset <3005> vis[3005];
LL Get(int i,int j){
LL res=0;
res+=(P[i].x-P[j].x)*(P[i].x-P[j].x);
res+=(P[i].y-P[j].y)*(P[i].y-P[j].y);
return res;
}
int main(){
scanf("%d",&N);
for(int i=1;i<=N;i++){
scanf("%I64d%I64d",&P[i].x,&P[i].y);
}
int Num=0;
for(int i=1;i<=N;i++){
for(int j=1;j<i;j++){
G[++Num].len=Get(i,j);
G[Num].s=i;
G[Num].t=j;
}
}
sort(G+1,G+Num+1,cmp);
LL Max=0;
for(int i=1;i<=Num;i++){
int u=G[i].s,v=G[i].t;
bitset <3005> tmp=vis[u]&vis[v];
if(tmp.any()){
Max=G[i].len;
break;
}
vis[u].set(v);
vis[v].set(u);
}
double res=sqrt(Max)/2;
printf("%.10f",res);
return 0;
}