平面最近点对

平面最近点对

利用分治法求解平面最近点对问题

相关资料

dx123 平面最近点对

例题

洛谷 P1257 平面上的最接近点对
洛谷 P1429 平面最近点对(加强版)
洛谷 P7883 平面最近点对(加强加强版)
$O(n\log^2n) $

//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long

using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*

*/
const int N = 2e5 + 5, inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f, mod = 998244353;
ll n;
pdd p[N], t[N];

double dis(pdd & i, pdd & j){
	double dx = i.first - j.first, dy = i.second - j.second;
	return sqrt(dx * dx + dy * dy);
}

double closedots(int l, int r){
	if(l == r) return 2e9;
	if(r == l + 1) return dis(p[l], p[r]);
	int mid = (l + r) >> 1;
	double d1, d2, d;
	d1 = closedots(l, mid); d2 = closedots(mid + 1, r);
	d = min(d1, d2);
	int id = 0;
	for(int i = l; i <= r; ++ i)
		if(fabs(p[i].first - p[mid].first) < d) t[++ id] = p[i];
	sort(t + 1, t + 1 + id, [](pdd& a, pdd& b){
		return a.second < b.second;
	});
	for(int i = 1; i < id; ++ i)
		for(int j = i + 1; j <= id && t[j].second - t[i].second < d; ++ j)
			d = min(d, dis(t[i], t[j]));
	return d;
}

void solve(){
	cin >> n;
	for(int i = 1; i <= n; ++ i) cin >> p[i].first >> p[i].second;
	sort(p + 1, p + 1 + n, [](pdd& a, pdd& b){
		return a.first < b.first || a.first == b.first && a.second < b.second;
	});
	double ans = closedots(1, n);
	cout << fixed << setprecision(4) << ans << '\n';
	return ;
}

signed main(){
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
	int _ = 1;
	// cin >> _;
	while(_ --){
		solve();
	}
	return 0;
}
posted on 2023-10-10 23:37  Qiansui  阅读(54)  评论(0编辑  收藏  举报