【题意】
给出n个点的坐标,求最近两点间的距离。
【输入格式】
第一行一个整数n(2 ≤ n ≤ 50000)。 下来n行,每行两个实数x和y表示点坐标。
【输出格式】
一行一个实数,表示最近两点间的距离(保留4位小数)。
【样例输入】
5
0 0
0 5
5 0
5 5
2 0
【样例输出】
2.0000
题解
扔一个欧几里得最短距离的模板
直接上kdtree
注意如果搜到自己了,那么不继承
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
struct node
{
LL mx[2],mn[2],d[2];int lc,rc;
node(){lc=rc=0;}
}tr[210000];int trlen;
void update(int x)
{
int lc=tr[x].lc,rc=tr[x].rc;
if(lc)
{
tr[x].mx[0]=max(tr[x].mx[0],tr[lc].mx[0]);
tr[x].mn[0]=min(tr[x].mn[0],tr[lc].mn[0]);
tr[x].mx[1]=max(tr[x].mx[1],tr[lc].mx[1]);
tr[x].mn[1]=min(tr[x].mn[1],tr[lc].mn[1]);
}
if(rc)
{
tr[x].mx[0]=max(tr[x].mx[0],tr[rc].mx[0]);
tr[x].mn[0]=min(tr[x].mn[0],tr[rc].mn[0]);
tr[x].mx[1]=max(tr[x].mx[1],tr[rc].mx[1]);
tr[x].mn[1]=min(tr[x].mn[1],tr[rc].mn[1]);
}
}
int cmpd;
bool cmp(node n1,node n2)
{
return n1.d[cmpd]<n2.d[cmpd] || n1.d[cmpd]==n2.d[cmpd] && n1.d[cmpd^1]<n2.d[cmpd^1];
}
int bt(int l,int r,int d)
{
int mid=(l+r)/2;int now;
cmpd=d;now=mid;
nth_element(tr+l,tr+mid,tr+r+1,cmp);
tr[now].mx[0]=tr[now].mn[0]=tr[now].d[0];
tr[now].mx[1]=tr[now].mn[1]=tr[now].d[1];
if(l<mid)tr[now].lc=bt(l,mid-1,d^1);
if(mid<r)tr[now].rc=bt(mid+1,r,d^1);
update(now);
return now;
}
LL nowx,nowy;int root,n;
LL minn;
LL sqr(LL x){return (x*x);}
LL dismin(int now,LL x,LL y)
{
LL ans=0;
if(x<tr[now].mn[0])ans+=sqr(tr[now].mn[0]-x);
if(x>tr[now].mx[0])ans+=sqr(x-tr[now].mx[0]);
if(y<tr[now].mn[1])ans+=sqr(tr[now].mn[1]-y);
if(y>tr[now].mx[1])ans+=sqr(y-tr[now].mx[1]);
return ans;
}
void solmin(int now)
{
LL d0=((tr[now].d[0]-nowx)*(tr[now].d[0]-nowx)+(tr[now].d[1]-nowy)*(tr[now].d[1]-nowy));
if(d0)minn=min(minn,d0);
LL d1=4e18,d2=4e18;
if(tr[now].lc)d1=dismin(tr[now].lc,nowx,nowy);
if(tr[now].rc)d2=dismin(tr[now].rc,nowx,nowy);
if(d1<d2)
{
if(d1<minn)solmin(tr[now].lc);
if(d2<minn)solmin(tr[now].rc);
}
else
{
if(d2<minn)solmin(tr[now].rc);
if(d1<minn)solmin(tr[now].lc);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld%lld",&tr[i].d[0],&tr[i].d[1]);
root=bt(1,n,0);
minn=4e18;
for(int i=1;i<=n;i++)
{
nowx=tr[i].d[0];nowy=tr[i].d[1];
solmin(root);
}
printf("%.4lf\n",sqrt(double(minn)));
return 0;
}