题意:
给定在同一平面中,同数量黑点与白点的坐标值,求其中最近黑白点对的距离。
—————————————————————————————————————————
大水题一遍过QAQ 稍微做点工作就是把同颜色的点,做上标记,同颜色的点就使其之间距离inf……
分治or暴力+剪枝都可以过。
————————————————————————————————————————————
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cmath> #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int inf=0x3f3f3f3f; const int maxn=200009; int n,T; struct node { bool flg; double x,y; }a[maxn],q[maxn]; double absolute(double u) {return u>=0?u:-u;} double min(double u,double v) {return u<v?u:v;} inline bool make_x(const node &u,const node &v) {return u.x<v.x;} inline bool make_y(const node &u,const node &v) {return u.y<v.y;} //计算两点间的距离 double length(const node &u,const node &v) { if(u.flg==v.flg) return inf; return sqrt((u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y)); } inline double solve(int u,int v) { if(u==v) return inf;//只有一个点 int k=0,m=(u+v)/2; double ans=min(solve(u,m),solve(m+1,v)); for(int i=u;i<=v;i++) if(absolute(a[i].x-a[m].x)<=ans) q[k++]=a[i]; sort(q+1,q+k+1,make_y);//预排序 for(int i=1;i<=k;i++) for(int j=i+1;j<=k;j++) { if((q[j].y-q[i].y)>ans) break; ans=min(ans,length(q[j],q[i])); } return ans; } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lf%lf",&a[i].x,&a[i].y); a[i].flg=0;//标记以便区分是否同集合 } for(int i=1;i<=n;i++) { scanf("%lf%lf",&a[i+n].x,&a[i+n].y); a[i+n].flg=1; } sort(a+1,a+2*n+1,make_x); printf("%.3lf\n",solve(1,2*n)); } return 0; }