时间太紧了 自己也没认真写,以前写过一次,竟然忘了,这次算是复习吧,LHW老师书上的代码上有六个点,这里没有那么简略,这里是全部的点,所以,时间复杂度虽然没超,也快了哈哈,还要判断,两个点必须在两个集和,这里在每个结构体里面加了个flag,AC代码放这里了:
//poj3714最近点对
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const double inf=1e50;
const int maxn=2e5+5;
struct pos{
double x;
double y;
int flag;
}a[200005],q[200005];
bool comp1(pos s1,pos s2){
return s1.x<s2.x;
}
bool comp2(pos s1,pos s2){
return s1.y<s2.y;
}
double dis(pos s1,pos s2){
return sqrt((s1.x-s2.x)*(s1.x-s2.x)+(s1.y-s2.y)*(s1.y-s2.y));
}
double dist(int l,int r){
if(l==r) return inf;
long long mid=(l+r)>>1;
double ans=min(dist(l,mid),dist(mid+1,r));
int cnt=0;
for(int i=l;i<=r;i++){
if(fabs(a[i].x-a[mid].x)<=ans) //找出符合条件的中间的点;
q[cnt++]=a[i];
}
sort(q,q+cnt,comp2);
for(int i=0;i<cnt;i++){
for(int j=i+1;j<cnt;j++){
if(q[i].flag==q[j].flag) continue;
if(q[j].y-q[i].y>ans) break;
ans=min(ans,dis(q[i],q[j]));
}
}
return ans;
}
int main()
{
int t,n;
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n*2;i++){
cin>>a[i].x>>a[i].y;
if(i<=n) a[i].flag=0;
else a[i].flag=1;
}
sort(a+1,a+2*n+1,comp1);
printf("%.3lf\n",dist(1,2*n));
}
return 0;
}
如有细节错误,请指正。
本文提供了一种解决POJ3714最近点对问题的方法,通过使用结构体存储坐标并引入标志位进行区分,实现对点集合的有效划分。采用分治策略,结合排序技巧,确保了算法的时间效率。
630

被折叠的 条评论
为什么被折叠?



