人类智慧球跳叫
  • 板块学术版
  • 楼主Link_Cut_Y
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/2/27 13:59
  • 上次更新2024/2/27 17:40:25
查看原帖
人类智慧球跳叫
519384
Link_Cut_Y楼主2024/2/27 13:59

经典智慧题平面最近点对,用的是 划分格子 的写法但是挂了。注意是 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);
}
2024/2/27 13:59
加载中...