P1429 平面最近点对(加强版)
题目背景
P7883 平面最近点对(加强加强版)
题目描述
给定平面上 \(n\) 个点,找出其中的一对点的距离,使得在这 \(n\) 个点的所有点对中,该距离为所有点对中最小的。
输入格式
第一行:\(n\) ,保证 \(2\le n\le 200000\) 。
接下来 \(n\) 行:每行两个整数:\(x\ y\) ,表示一个点的行坐标和列坐标,中间用一个空格隔开。
输出格式
仅一行,一个实数,表示最短距离,精确到小数点后面 \(4\) 位。
输入输出样例 #1
输入 #1
3
1 1
1 2
2 2
输出 #1
1.0000
说明/提示
数据保证 \(0\le x,y\le 10^9\)
AC代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6;struct Node{int x,y;
} s[maxn];bool cmp(const Node &a,const Node &b){if(a.x==b.x) return a.y<b.y;return a.x<b.x;
}bool cmp1(const int &a,const int &b){return s[a].y<s[b].y;
}ll dis(int a,int b){return (ll)(s[a].x-s[b].x)*(s[a].x-s[b].x)+(ll)(s[a].y-s[b].y)*(s[a].y-s[b].y);
}int tmp[maxn];ll memrge(int l,int r){if(l>=r) return LLONG_MAX;if(l+1==r) return dis(l,r);int mid=(l+r)>>1;ll d1=memrge(l,mid);ll d2=memrge(mid+1,r);ll d=min(d1,d2);int t=0;for (int i = l; i <= r; i++){if ((s[i].x - s[mid].x) * (s[i].x - s[mid].x) < d){tmp[t++]=i;}}sort(tmp,tmp+t,cmp1);for(int i=0;i<t;i++){for (int j = i + 1; j < t && (s[tmp[j]].y - s[tmp[i]].y) * (s[tmp[j]].y - s[tmp[i]].y) < d; j++){d=min(d,dis(tmp[i],tmp[j]));}}return d;
}int main(){int n;cin>>n;for(int i=1;i<=n;i++){cin>>s[i].x>>s[i].y;}double ans;sort(s+1,s+n+1,cmp);ans=memrge(1,n);ans=sqrt(ans);printf("%.4lf\n",ans);return 0;
}