处理出每个点对之间的距离,把它们看成边,问题就等价于找一个三角形,使它的最短边最长。
把这些边从大到小排序,维护每个点当前能到达点集。遍历每条边时,看两个端点能到达的点集有没有交集,如果有那么交集的点就是离两个端点距离都大于当前这条边的,那么这个三角型的最短边就是当前这条边。
收获:
维护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; }