洛谷 P1429 平面最近点对 (分治)

题目:传送门

题意:给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的

2≤n≤200000

 

思路:

截取自洛谷题解的 ->

 

 

#include <bits/stdc++.h>
#define LL long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF INT_MAX
#define inf LLONG_MAX
#define PI acos(-1)
#define fir first
#define sec second
using namespace std;

const int N = 2e5 + 5;
const double eps = 1e-8;

struct Point {
    double x, y;
    Point(double x = 0, double y = 0) : x(x), y(y) { }
};

int dcmp(double x) {
    if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
}

Point operator + (Point A, Point B) { return Point(A.x + B.x, A.y + B.y); }
Point operator - (Point A, Point B) { return Point(A.x - B.x, A.y - B.y); }
Point operator * (Point A, double p) { return Point(A.x * p, A.y * p); }
Point operator / (Point A, double p) { return Point(A.x / p, A.y / p); }

bool cmp2(Point A, Point B) {
    return dcmp(A.y - B.y) < 0;
}

bool cmp1(Point A, Point B) {
    return dcmp(A.x - B.x) == 0 ? dcmp(A.y - B.y) < 0 : dcmp(A.x - B.x) < 0;
}

Point P[N], tmp[N];

double Dis(Point A, Point B) {
    return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}

double solve(int l, int r) {
    if(l == r) return 1e20;
    if(l + 1 == r) return Dis(P[l], P[r]);
    int mid = (l + r) >> 1;
    double dis1 = solve(l, mid);
    double dis2 = solve(mid + 1, r);
    double dis = min(dis1, dis2);
    int tot = 0;
    rep(i, l, r) {
        if(fabs(P[mid].x - P[i].x) <= dis) tmp[++tot] = P[i];
    }
    sort(tmp + 1, tmp + 1 + tot, cmp2);
    rep(i, 1, tot) rep(j, i + 1, tot) {
        if(tmp[j].y - tmp[i].y > dis) break;
        dis = min(dis, Dis(tmp[i], tmp[j]));
    }
    return dis;
}

int main() {

    int n;
    scanf("%d", &n);
    rep(i, 1, n) scanf("%lf %lf", &P[i].x, &P[i].y);
    sort(P + 1, P + 1 + n, cmp1);
    printf("%.4f\n", solve(1, n));
    return 0;
}

 

posted on 2020-03-14 18:46  Willems  阅读(178)  评论(0编辑  收藏  举报

导航