平面最近点对
平面最近点对
利用分治法求解平面最近点对问题
相关资料
时间复杂度可以优化到 \(O(n\log n)\)
例题
洛谷 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;
}
加强加强版通过代码 (251020)
const int N = 4e5 + 5, inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f, mod = 998244353;
ll n;
pll p[N], t[N];
ll dis(pll & i, pll & j){
ll dx = i.first - j.first, dy = i.second - j.second;
return dx * dx + dy * dy;
}
ll dpow(ll x, ll y){
return (x - y) * (x - y);
}
ll closedots(int l, int r){
if(l == r) return 1e18;
if(r == l + 1) return dis(p[l], p[r]);
int mid = (l + r) >> 1;
ll 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(dpow(p[i].first, p[mid].first) < d) t[++ id] = p[i];
sort(t + 1, t + 1 + id, [](pll& a, pll& b){
return a.second < b.second;
});
for(int i = 1; i < id; ++ i)
for(int j = i + 1; j <= id && dpow(t[i].second, t[j].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, [](pll& a, pll& b){
return a.first < b.first || a.first == b.first && a.second < b.second;
});
ll ans = closedots(1, n);
cout << ans << '\n';
return ;
}
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/17756050.html

浙公网安备 33010602011771号