This is an attempted O(NlogN) solution to the closest pair problem, written in C++11. I used std::complex for geometry. The comparators may be confusing, to the explain: cmp
initially sorts the points by x and then y, and compare_y
sorts the points in the bounding box by y value.
The following are the errors I get, followed by my code.
cp.cpp: In function ‘int main()’:
cp.cpp:49:95: error: expected primary-expression before ‘)’ token
for (set<point>::iterator it = s.lower_bound(s.begin(), s.end(), t1, compare_y); it < s.upper_bound(s.begin(), s.end(), t2, compare_y); ++it) {
^
cp.cpp:49:150: error: expected primary-expression before ‘)’ token
for (set<point>::iterator it = s.lower_bound(s.begin(), s.end(), t1, compare_y); it < s.upper_bound(s.begin(), s.end(), t2, compare_y); ++it) {
#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;
// define x, y as real(), imag()
typedef complex<double> point;
#define x real()
#define y imag()
bool cmp(point a, point b) {
if (a.x < b.x) return true;
if (a.x - b.x < EPS && a.y < b.y) return true;
return false;
}
struct compare_y {
bool operator() (const point& lhs, const point& rhs) const{
if (lhs.y < rhs.y) return true;
}
};
int main() {
int n;
while (scanf("%d", &n) && n != 0) {
vector<point> coord;
for (int i=0; i<n; ++i) {
double xi, yi;
scanf("%lf%lf", &xi, &yi);
point t(xi, yi);
coord.push_back(t);
}
sort(coord.begin(), coord.end(), cmp);
double h = 10000000;
set<point, compare_y> s;
s.insert(coord[0]);
for (int i=1; i<n; ++i) {
for (auto pt:s) {
if (abs(pt-coord[i])+EPS > h) { // bound by x
s.erase(pt);
}
}
point t1 = coord[i]; t1.imag(t1.y - h);
point t2 = coord[i]; t2.imag(t2.y + h);
for (set<point>::iterator it = s.lower_bound(s.begin(), s.end(), t1, compare_y); it < s.upper_bound(s.begin(), s.end(), t2, compare_y); ++it) {
h = min(h, abs(*it-coord[i]));
}
s.insert(coord[i]);
}
if (h + EPS >= 10000)
printf("INFINITY\n");
else
printf("%.4lf\n", h);
}
}