题意:station和agent分别有n(1<=n<=100000)个点,求不同类别的最近点对距离。
题解:http://blog.csdn.net/w397090770/article/details/7295797 这里讲的很好。
#include <iostream> #include <cstdio> #include <memory.h> #include <algorithm> #include <cmath> #define MAX(a , b) ((a) > (b) ? (a) : (b)) #define MIN(a , b) ((a) < (b) ? (a) : (b)) #define ABS(x) ((x) >= 0 ? (x) : (-(x))) using namespace std; const double inf = 1e50; const int maxn = 100002; struct P { double x,y; int type; }po[maxn << 1]; int middle[maxn << 1]; int n; bool cmpx(P a,P b) { return a.x < b.x; } bool cmpy(int a,int b) { return po[a].y < po[b].y; } void read() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%lf %lf",&po[i].x,&po[i].y); po[i].type = 0; } for(int i=n;i<2*n;i++) { scanf("%lf %lf",&po[i].x,&po[i].y); po[i].type = 1; } n <<= 1; sort(po , po+n , cmpx); return; } double dis(int i,int j) { if(po[i].type == po[j].type) return inf; return sqrt((po[i].x - po[j].x) * (po[i].x - po[j].x) + (po[i].y - po[j].y) * (po[i].y - po[j].y)); } double Mindis(int l,int r) { if(l >= r-1) return dis(l , r); int mid = (l + r) >> 1; double a = Mindis(l , mid); double b = Mindis(mid+1 , r); double d = MIN(a , b); int top = 0; for(int i=l;i<=r;i++) { if(ABS(po[i].x - po[mid].x) <= d) { middle[top++] = i; } } sort(middle , middle + top , cmpy); for(int i=0;i<top;i++) { int to = MIN(top-1 , i+6); for(int j=i+1;j<=to;j++) { d = MIN(d , dis(middle[i] , middle[j])); } } return d; } int main() { int cas; scanf("%d",&cas); while(cas--) { read(); printf("%.3f\n",Mindis(0,n-1)); } return 0; }