标签:
解题思路:
分治法求平面最近点对,点分成两部分,加个标记就好了。
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <iomanip> #include <string.h> #define LL long long using namespace std; const int MAXN = 200000 + 10; const double INF = 1e100; struct Point { double x, y; int flag; }P[MAXN]; int N; Point vec[MAXN]; bool cmp_x(Point a, Point b) { return a.x < b.x; } bool cmp_y(Point a, Point b) { return a.y < b.y; } double dis(Point a, Point b) { double dx = a.x - b.x; double dy = a.y - b.y; return sqrt(dx * dx + dy * dy); } double solve(Point *a, int l, int r) { if(l == r) return INF; if(l + 1 == r) { if(P[l].flag == P[r].flag) return INF; return dis(P[l], P[r]); } int m = (l + r) >> 1; double d = solve(a, l, m); d = min(d, solve(a, m + 1, r)); int sz = 0; for(int i=l;i<=r;i++) { if(fabs(P[i].x - P[m].x) <= d) vec[sz++] = P[i]; } sort(vec, vec + sz, cmp_y); for(int i=0;i<sz;i++) { for(int j=i+1;j<sz;j++) { if(fabs(vec[i].y - vec[j].y) >= d) break; if(vec[i].flag != vec[j].flag) { double rs = dis(vec[i], vec[j]); if(rs < d) d = rs; } } } return d; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &N); for(int i=0;i<N;i++) { scanf("%lf%lf", &P[i].x, &P[i].y); P[i].flag = 0; } for(int i=0;i<N;i++) { scanf("%lf%lf", &P[i + N].x, &P[i + N].y); P[i + N]. flag = 1; } N <<= 1; sort(P, P + N, cmp_x); double ans = solve(P, 0, N - 1); printf("%.3f\n", ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/moguxiaozhe/article/details/46959525