給定平面上 N (≤105) 個點,求最近點對距離除以 2(即最大不重疊圓半徑)。經典最近點對問題。
struct Point { double x, y; };
bool cmpX(Point a, Point b) { return a.x < b.x; }
bool cmpY(Point a, Point b) { return a.y < b.y; }
double dist2(Point a, Point b) { ... }
double solve(Point p[], int l, int r) {
if (r - l + 1 <= 3) { // brute force
double d = INF;
for (int i=l;i<=r;++i)
for (int j=i+1;j<=r;++j)
d = min(d, dist2(p[i], p[j]));
sort(p+l, p+r+1, cmpY);
return sqrt(d);
}
int mid = (l+r)/2;
double midX = p[mid].x;
double d = min(solve(p, l, mid), solve(p, mid+1, r));
// merge by y
static Point tmp[MAXN];
int cnt = 0;
for (int i=l;i<=r;++i)
if (fabs(p[i].x - midX) < d)
tmp[cnt++] = p[i];
// check strip
for (int i=0;i
最近點對是分治法的教科書級例題。關鍵在於「合併階段只需檢查常數個點」的幾何性質證明,以及用 inplace_merge 維護 y 序實現 O(N log N) 總複雜度。模板值得熟練掌握。