Closest Pair
For given n points in metric space, find the distance of the closest points.
Input
n x0 y0 x1 y1 : xn−1 yn−1
The first integer n is the number of points.
In the following n lines, the coordinate of the i-th point is given by two real numbers xi and yi. Each value is a real number with at most 6 digits after the decimal point.
Output
Print the distance in a line. The output values should be in a decimal fraction with an error less than 0.000001.
Constraints
- 2 ≤ n ≤ 100,000
- -100 ≤ x, y ≤ 100
Sample Input 1
2 0.0 0.0 1.0 0.0
Sample Output 1
1.000000
Sample Input 2
3 0.0 0.0 2.0 0.0 1.0 1.0
Sample Output 2
1.41421356237
题意:
在平面中给定n个点对,要求找到这n个点对中的最小距离并输出。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const double eps = 1e-10;
typedef long long LL;
int dcmp(double x, double y)
{
if (fabs(x - y) <= eps) return 0;
if (x > y) return 1;
return -1;
}
struct Point
{
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) { }
}p[N];
int n;
bool cmpx(Point A, Point B)
{
if (dcmp(A.x, B.x) == 0) return A.y < B.y;
return A.x < B.x;
}
bool cmpy(Point A, Point B)
{
return A.y < B.y;
}
double get_dist2(Point A, Point B)
{
double dx = A.x - B.x, dy = A.y - B.y;
return dx * dx + dy * dy;
}
double merge(Point p[], int l, int r)
{
double d = INF;
if (l == r) return d;
if (l + 1 == r) return get_dist2(p[l], p[r]);
int mid = l + r >> 1;
d = min(merge(p, l, mid), merge(p, mid + 1, r));
int cnt = 0;
vector<Point> tmp(r - l + 3);
for (int i = l; i <= r; i++)
if ((p[mid].x - p[i].x) * (p[mid].x - p[i].x) <= d)
tmp[++cnt] = p[i];
sort(tmp.begin() + 1, tmp.begin() + cnt + 1, cmpy);
for(int i = 1; i <= cnt; i ++)
for (int j = i + 1; j <= cnt; j++)
{
if ((tmp[j].y - tmp[i].y) * (tmp[j].y - tmp[i].y) > d) break;
d = min(d, get_dist2(tmp[i], tmp[j]));
}
return d;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) cin >> p[i].x >> p[i].y;
sort(p + 1, p + 1 + n, cmpx);
double ans = merge(p, 1, n);
printf("%.11lf\n", sqrt(ans));
return 0;
}