杭电OJ Quoit Design 需要二刷 *平面最短距离点对问题

基本思想:

典型的平面最短举例点对得问题,专题总结过;

关键点:

无;

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct point {
    double x;
    double y;
};

const int maxn = 100100;
const double INF = 10000000;
int n;
point num[maxn];

bool cmp1(point a, point b) {
    if (a.x != b.x)
        return a.x < b.x;
    return a.y < b.y;
}

bool cmp2(int a, int b) {
    return num[a].y < num[b].y;
}

double cnt(int a, int b) {
    return sqrt(pow(num[a].x - num[b].x, 2) + pow(num[a].y - num[b].y, 2));
}

double charge(int l, int r) {
    if (l == r)
        return INF;
    if (l + 1 == r) {
        return cnt(l, r);
    }
    int mid = (r + l) / 2;
    double d1 = charge(l, mid);
    double d2 = charge(mid + 1, r);
    double d = min(d1, d2);
    //进行合并计算;
    vector<int>vec;
    for (int i = l; i <= r; i++) {
        if (fabs(num[i].x - num[mid].x) <= d) {
            vec.push_back(i);
        }
    }
    sort(vec.begin(), vec.end(), cmp2);
    for (int i = 0; i < vec.size(); i++) {
        for (int j = i + 1; j < vec.size() && num[vec[j]].y - num[vec[i]].y < d; j++) {
            double dis = cnt(vec[i], vec[j]);
            if (dis < d)
                d = dis;
        }
    }
    return d;
}


int main() {
    while (cin >> n) {
        if (n == 0)
            break;
        for (int i = 0; i < n; i++) {
            cin >> num[i].x >> num[i].y;
        }
        sort(num, num + n, cmp1);
        printf("%.2lf\n", charge(0, n - 1) / 2);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/songlinxuan/p/12666075.html