您的位置:首页 > 其它

bzoj3053 The Closest M Points [kd-tree]

2018-03-22 19:56 375 查看
Description:

kk维空间询问第mm近点对。

Solution:

kd−treekd−tree裸题。

#include <bits/stdc++.h>
using namespace std;
const int N = 305;
struct P {
double x, y;
P() {}
P(double _x, double _y) : x(_x), y(_y) {}
P friend operator + (const P &a, const P &b) {
return P(a.x + b.x, a.y + b.y);
}
P friend operator - (const P &a, const P &b) {
return P(a.x - b.x, a.y - b.y);
}
P friend operator * (const P &a, double b) {
return P(a.x * b, a.y * b);
}
double friend operator * (const P &a, const P &b) {
return a.x * b.y - a.y * b.x;
}
} p
, a
;
struct L {
P p, v;
double ang;
L() {}
L(P _p, P _v) : p(_p), v(_v) { ang = atan2(v.y, v.x); }
} l
, q
;
int n, m, head, tail;
double ans = 1e9;
P inter(L a, L b) {
P u = a.p - b.p;
double d = (b.v * u) / (a.v * b.v);
return a.p + a.v * d;
}
bool left(L a, P b) {
return (b - a.p) * a.v < 0;
}
bool cmp(L a, L b) {
return a.ang == b.ang ? !left(a, b.p) : a.ang < b.ang;
}
int main() {
scanf("%d", &n);
++n;
for(int i = 2; i <= n; ++i) {
scanf("%lf", &p[i].x);
}
for(int i = 2; i <= n; ++i) {
scanf("%lf", &p[i].y);
}
p[1].x = p[2].x;
p[1].y = 1000001;
p[n + 1].x = p
.x;
p[n + 1].y = 1000001;
for(int i = 1; i <= n; ++i) {
l[i] = L(p[i], p[i + 1] - p[i]);
}
sort(l + 1, l + n + 1, cmp);
l[++m] = l[1];
for(int i = 2; i <= n; ++i) {
if(l[i].ang != l[m].ang) {
l[++m] = l[i];
}
}
q[++tail] = l[1];
q[++tail] = l[2];
for(int i = 3; i <= m; ++i) {
while(head < tail && !left(l[i], inter(q[tail], q[tail - 1]))) {
--tail;
}
while(head < tail && !left(l[i], inter(q[head], q[head + 1]))) {
++head;
}
q[++tail] = l[i];
}
while(head < tail && !left(q[tail], inter(q[head], q[head + 1]))) {
++head;
}
while(head < tail && !left(q[head], inter(q[tail], q[tail - 1]))) {
--tail;
}
m = 0;
for(int i = head; i < tail; ++i) {
a[++m] = inter(q[i], q[i + 1]);
}
for(int i = 1; i <= n; ++i) {
P t;
t.x = 0;
t.y = 1;
for(int j = 1; j < m; ++j) {
if(a[j].x <= p[i].x && a[j + 1].x >= p[i].x) {
P tmp = inter(L(p[i], t), L(a[j], a[j] - a[j + 1]));
ans = min(ans, fabs(tmp.y - p[i].y));
}
}
}
for(int i = 1; i <= m; ++i) {
P t;
t.x = 0;
t.y = 1;
for(int j = 1; j < n; ++j) {
if(p[j].x <= a[i].x && p[j + 1].x >= a[i].x) {
P tmp = inter(L(a[i], t), L(p[j], p[j] - p[j + 1]));
ans = min(ans, fabs(a[i].y - tmp.y));
}
}
}
printf("%.3f\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: