最近点对问题
平面直角坐标系上有若干个点,求其任意点对距离的最小值
模板1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40struct Node {
double x, y;
int tag;
Node() {}
Node(double x, double y, int tag = 0): x(x), y(y), tag(tag) {}
bool operator <(const Node s)const { return x < s.x || (x == s.x && y < s.y); }
}p[N], tmp[N];
bool cmp(Node x, Node y) { return x.y < y.y || (x.y == y.y && x.x < y.x); }
double getdis(Node x, Node y) { return sqrt(pow(x.x - y.x, 2) + pow(x.y - y.y, 2)); }
double getmin(int l, int r) {
if (l == r)return 0;
if (r - l == 1)return getdis(p[l], p[r]);
if (r - l == 2) {
double ans = getdis(p[l], p[l + 1]);
ans = min(ans, getdis(p[l + 1], p[r]));
ans = min(ans, getdis(p[l], p[r]));
return ans;
}
int mid = l + r >> 1, tot = 0;
double ans = min(getmin(l, mid), getmin(mid + 1, r));
for (int i = l; i <= mid; ++i)
if (p[mid].x - p[i].x <= ans)
tmp[tot++] = Node(p[i].x, p[i].y, 0);
for (int i = mid + 1; i <= r; ++i)
if (p[i].x - p[mid].x <= ans)
tmp[tot++] = Node(p[i].x, p[i].y, 1);
sort(tmp, tmp + tot, cmp);
for (int i = 0; i < tot; ++i) {
if (tmp[i].tag)continue;
for (int j = 1; j <= 7 && i + j < tot; ++j) {
if (!tmp[j].tag)continue;
ans = min(ans, getdis(tmp[i], tmp[i + j]));
}
}
return ans;
}
void init(int n) {
for (int i = 0; i < n; ++i)p[i] = Node(fast_IO::read(), fast_IO::read());
sort(p, p + n);
}
模板(by 俊杰)
1 |
|