Untitled

 avatar
unknown
c_cpp
19 days ago
2.1 kB
5
Indexable
struct Point {
    long long x, y;
};

long long distSquare(const Point &p1, const Point &p2) {
    long long dx = p1.x - p2.x;
    long long dy = p1.y - p2.y;
    return dx*dx + dy*dy;
}

long long bruteForce(const vector<Point> &points, int low, int high) {
    long long minDist = LLONG_MAX;
    for (int i = low; i <= high; ++i) {
        for (int j = i + 1; j <= high; ++j) {
            long long distance = distSquare(points[i], points[j]);
            if (distance < minDist) {
                minDist = distance;
            }
        }
    }
    return minDist;
}

long long closestUtil(vector<Point> &points, int low, int high) {
    if (high - low <= 3) {
        return bruteForce(points, low, high);
    }
    int mid = (low + high) / 2;
    long long midX = points[mid].x;
    long long dLeft  = closestUtil(points, low, mid);
    long long dRight = closestUtil(points, mid + 1, high);
    long long d = min(dLeft, dRight);
    vector<Point> strip;
    strip.reserve(high - low + 1);
    for (int i = low; i <= high; ++i) {
        long long dx = points[i].x - midX;
        if (dx * dx < d) {
            strip.push_back(points[i]);
        }
    }
    sort(strip.begin(), strip.end(), [](const Point &a, const Point &b) {
        return a.y < b.y;
    });
    for (int i = 0; i < (int)strip.size(); ++i) {
        for (int j = i + 1; j < (int)strip.size(); ++j) {
            long long dy = strip[j].y - strip[i].y;
            if (dy * dy >= d) {
                break;
            }
            long long curDist = distSquare(strip[i], strip[j]);
            if (curDist < d) {
                d = curDist;
            }
        }
    }
    return d;
}

long closestSquareDistance(vector<int> x, vector<int> y) {
    int n = (int)x.size();
    if (n < 2) {
        return 0; 
    }
    vector<Point> points(n);
    for (int i = 0; i < n; ++i) {
        points[i].x = x[i];
        points[i].y = y[i];
    }
    sort(points.begin(), points.end(), [](const Point &a, const Point &b){
        return a.x < b.x;
    });
    long long result = closestUtil(points, 0, n - 1);
    return (long)result;
}
Leave a Comment