经典智慧题平面最近点对,用的是 划分格子 的写法但是挂了。注意是 WA 不是 T。求调教。
#include <unordered_map>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#define x first
#define y second
#define int long long
#define rep(i, a, b) for (int i = (a); i <= (b); i ++ )
using namespace std;
using ULL = unsigned long long;
using PII = pair<int, int>;
unordered_map<ULL, vector<int>> bin;
const int N = 400010;
const ULL B = 1331331ull;
const int dx[] = {0, 1, 1, 0, -1, -1, -1, 0, 1};
const int dy[] = {0, 0, 1, 1, 1, 0, -1, -1, -1};
PII p[N]; int ans, n;
ULL hs(int x, int y) {
return 1ull * x * 1000000ull * B + 1ull * y;
}
void build(double d) {
bin.clear(); rep(i, 1, n) {
int x = (int)p[i].x / d, y = (int)p[i].y / d;
bin[hs(x, y)].push_back(i);
}
}
double dis(PII a, PII b) {
double dx = a.x - b.x, dy = a.y - b.y;
return (double)sqrt(dx * dx + dy * dy);
}
int dist(PII a, PII b) {
int dx = a.x - b.x, dy = a.y - b.y;
return dx * dx + dy * dy;
}
signed main() {
scanf("%lld", &n);
rep(i, 1, n) scanf("%lld%lld", &p[i].x, &p[i].y);
rep(i, 1, n) p[i].x += (int)1e7, p[i].y += (int)1e7;
sort(p + 1, p + n + 1); double d = dis(p[1], p[2]);
ans = dist(p[1], p[2]); build(d);
rep(i, 3, 3) {
int x = (int)p[i].x / d, y = (int)p[i].y / d, flg = 0;
rep(j, 0, 8) if (bin[hs(x + dx[j], y + dy[j])].size())
for (auto k : bin[hs(x + dx[j], y + dy[j])]) {
if (i != k and dist(p[i], p[k]) < ans) {
d = dis(p[i], p[k]), flg = 1;
ans = dist(p[i], p[k]);
}
}
if (flg) build(d);
}
printf("%lld\n", ans);
}