Tìm khoảng cách lớn nhất, nhỏ nhất giữa hai cặp điểm
Tìm khoảng cách lớn nhất giữa hai cặp điểm
Bài toán: Trên mặt phẳng tọa độ cho \(N\) điểm tọa độ nguyên \((X_i, Y_i)\) \((2 \le N \le 10^5; \lvert X_i \rvert, \lvert Y_i \rvert \le 10^9)\), tìm bình phương khoảng cách lớn nhất của hai cặp điểm bất kì trong tập điểm đã cho.
Độ phức tạp: \(O(Nlog(N))\)
#include <bits/stdc++.h>
using namespace std;
#define Point Vector
struct Vector {
int x, y;
Vector() {}
Vector(int _x, int _y) {
x = _x; y = _y;
}
Vector operator - (const Vector &v) const {
return Vector(x - v.x, y - v.y);
}
long long sqrLen() const {
return 1LL * x * x + 1LL * y * y;
}
long long operator % (const Vector &v) const {
return 1LL * x * v.y - 1LL * y * v.x;
}
friend long long cross (const Vector &a, const Vector &b, const Vector &c) {
return (b-a) % (c-b);
}
friend bool CCW(const Point &a, const Point &b, const Point &c) {
return cross(a, b, c) > 0;
}
friend bool CW(const Point &a, const Point &b, const Point &c) {
return cross(a, b, c) < 0;
}
friend long long sqrDist(const Point &a, const Point &b) {
return (a-b).sqrLen();
}
bool operator < (const Vector &v) const {
return make_pair(x, y) < make_pair(v.x, v.y);
}
bool operator == (const Vector &v) const {
return make_pair(x, y) == make_pair(v.x, v.y);
}
};
int numPoint;
vector<Point> points;
vector<Point> ConvexHull(vector<Point> points) {
sort(points.begin(),points.end());
points.resize(unique(points.begin(),points.end()) - points.begin());
if ((int)points.size() <= 2) return points;
Point lef = points.front();
Point rig = points.back();
vector<Point> up, down;
for (int i = 0; i < (int)points.size(); ++i) {
if (i == 0 || i == (int)points.size()-1 || CW(lef, points[i], rig)) {
while ((int)up.size() > 1 && !CW(up[(int)up.size()-2], up.back(), points[i]))
up.pop_back();
up.push_back(points[i]);
}
if (i == 0 || i == (int)points.size()-1 || CCW(lef, points[i], rig)) {
while ((int)down.size() > 1 && !CCW(down[(int)down.size()-2], down.back(), points[i]))
down.pop_back();
down.push_back(points[i]);
}
}
for (int i = (int)up.size()-2; i > 0; --i) {
down.push_back(up[i]);
}
return down;
}
long long maximumDistance(vector<Point> points) {
vector<Point> hull = ConvexHull(points);
long long res = 0;
for (int i = 0, j = 0; i < (int)hull.size(); ++i) {
while (j < (int)hull.size()-1 && sqrDist(hull[i], hull[j]) < sqrDist(hull[i], hull[j+1])) {
j++;
}
res = max(res, sqrDist(hull[i], hull[j]));
}
return res;
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> numPoint;
for (int i = 0; i < numPoint; ++i) {
int x, y;
cin >> x >> y;
points.emplace_back(x, y);
}
cout << maximumDistance(points);
return 0;
}
Tìm khoảng cách nhỏ nhất giữa hai cặp điểm
Đề bài: https://cses.fi/problemset/task/2194
Độ phức tạp: \(O(Nlog(N))\)
#include <bits/stdc++.h>
using namespace std;
#define Point Vector
struct Vector {
int x, y;
Vector() {}
Vector(int _x, int _y) {
x = _x; y = _y;
}
Vector operator - (const Vector &v) const {
return Vector(x-v.x,y-v.y);
}
long long sqrLen() const {
return 1LL * x * x + 1LL * y * y;
}
friend long long sqrDist(const Point &a, const Point &b) {
return (a-b).sqrLen();
}
bool operator < (const Vector &v) const {
return make_pair(y, x) < make_pair(v.y, v.x);
}
};
const long long INFLL = 9e18;
const int INF = 2e9;
int numPoint;
vector<Point> points;
long long mySqr(long long x) {
return x * x;
}
long long ceilSqrt(long long x) {
long long i = sqrt(x);
while (i*i > x) i--;
while (i*i < x) i++;
return i;
}
long long minimumDistance(vector<Point> points) {
set<Point> heap;
long long cur = INFLL;
sort(points.begin(), points.end(), [&](const Point &a, const Point &b) {
return make_pair(a.x, a.y) < make_pair(b.x, b.y);
});
for (int i = 0, j = 0; i < (int)points.size(); ++i) {
while (mySqr(points[i].x-points[j].x) >= cur) {
heap.erase(points[j]);
j++;
}
if (!heap.empty()) {
long long tmp = ceilSqrt(cur);
auto down = heap.upper_bound(Point(points[i].x, max(-1LL * INF, points[i].y - tmp)));
auto up = heap.upper_bound(Point(points[i].x, min(1LL * INF, points[i].y + tmp)));
for (auto it = down; it != up; ++it) {
if (sqrDist(points[i], *it) < cur) {
cur = sqrDist(points[i], *it);
}
}
}
heap.insert(points[i]);
}
return cur;
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> numPoint;
for (int i = 0; i < numPoint; ++i) {
int x, y;
cin >> x >> y;
points.emplace_back(x, y);
}
cout << minimumDistance(points);
return 0;
}