[P1427] 平面最近点对加强版 - 分治
Posted mollnn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[P1427] 平面最近点对加强版 - 分治相关的知识,希望对你有一定的参考价值。
暴力沿着 (x) 轴方向分治,每次合并时,利用当前已有 (ans),只保留 ((mid-ans,mid+ans)) 内的点,将它们按 (y) 排序,对每个点找它上面 (ans) 内的点,只枚举这范围内的点对来计算答案即可
#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
const double inf = 1e18;
struct point {
double x,y;
bool operator < (const point &b) {
if(x!=b.x) return x<b.x;
else return y<b.y;
}
} p[N];
bool cmp(const point &a, const point &b) {
return a.y < b.y;
}
double dist2(point a,point b) {
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int n;
double solve(int l,int r) {
if(l==r) {
return inf;
}
else {
int mid=(l+r)/2;
double pos=p[mid].x;
double ans=inf;
ans=min(ans,solve(l,mid));
ans=min(ans,solve(mid+1,r));
int pl=mid,pr=mid+1;
while(pow(p[pl].x-pos,2)<=ans && pl>=l) --pl;
++pl;
while(pow(p[pr].x-pos,2)<=ans && pr<=r) ++pr;
--pr;
vector <point> v;
for(int i=pl;i<=pr;i++) v.push_back(p[i]);
sort(v.begin(),v.end(),cmp);
for(int i=0;i<v.size();i++) {
for(int j=i+1;j<v.size();j++) {
if(pow(fabs(v[i].y-v[j].y),2)>ans) break;
ans=min(ans,dist2(v[i],v[j]));
}
}
return ans;
}
}
signed main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++) {
cin>>p[i].x>>p[i].y;
}
sort(p+1,p+n+1);
printf("%.4lf
",sqrt(solve(1,n)));
}
以上是关于[P1427] 平面最近点对加强版 - 分治的主要内容,如果未能解决你的问题,请参考以下文章