-
Notifications
You must be signed in to change notification settings - Fork 0
/
closest pair of points using divide and conquer.cpp
100 lines (86 loc) · 2.63 KB
/
closest pair of points using divide and conquer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int>> point;
struct op
{
bool operator()(const pair<int,int> &a , const pair<int,int> &b) const
{
if(a.first == b.first) return a.second < b.second;
return a.first < b.first;
}
};
long double distance(pair<int,int> &a , pair<int,int> &b)
{
long double foo = b.second - a.second; foo = foo * foo;
long double res = b.first - a.first; res = res * res;
long double sum = foo + res;
sum = sqrt(sum);
return sum;
}
long double brute(vector<pair<int,int>> &point , int n)
{
long double minn = FLT_MAX;
for(int i = 0 ; i < n ; ++i){
for(int j = i + 1; j < n ; ++j){
if(distance(point[i] , point[j]) < minn) minn = distance(point[i] , point[j]);
}
}
return minn ;
}
long double min(long double a , long double b)
{
if(a <= b) return a;
return b;
}
struct comp
{
bool operator()(const pair<int,int> &a , const pair<int,int> &b) const
{
return a.second < b.second;
}
};
long double closestsplitpoints(vector<pair<int,int>> strip , int size , long double delta)
{
sort(strip.begin() , strip.end() , comp());
long double minn = delta;
for(int i = 0 ; i < size ; ++i){
for(int j = i + 1 ; j < size && (strip[j].second - strip[i].second) < minn; ++j){
if(distance(strip[i] , strip[j]) < minn){
minn = distance(strip[i] , strip[j]);
}
}
}
return minn;
}
long double solve(vector<pair<int,int>> point , int n)
{
if(n <= 3) return brute(point , n);
int mid = n / 2 ;
pair<int,int> midpoint = point[mid];
vector<pair<int,int>> pointsleft , pointsright;
for(int i = 0; i <= mid ; ++i) pointsleft.push_back({point[i].first , point[i].second});
for(int i = mid + 1 ; i < n ; ++i) pointsright.push_back({point[i].first , point[i].second});
long double distance_left = solve(pointsleft , mid);
long double distance_right = solve(pointsright , n - mid);
long double delta = min(distance_left , distance_right);
vector<pair<int,int>> strip;
for(int i = 0 ; i < n ; ++i){
if(abs(point[i].first - midpoint.first) < delta){
strip.push_back(point[i]);
}
}
return min(delta , closestsplitpoints(strip , int(strip.size()) , delta));
}
int main()
{
int n ;
cin >> n ;
for(int i = 1; i <= n ; ++i){
int x , y;
cin >> x >> y;
point.push_back({x,y});
}
sort(point.begin() , point.end(), op());
cout << solve(point , n) ;
return 0;
}