问题:

对$n$个不同的数构成的数组$A[1..n]$进行排序,其中$n=2^k$。

解析:

分治思想,对于每个点堆,分成l和r两个点集,分别求每个点集中点的最近对。三种情况:

①$  l = r $:只有一个点,返回 $inf$

②$l = r – 1$:两个点,返回两个点的点距。

③$l = r – 2$:三个点,计算两两点之间的距离,返回最小值。

④超过三个点,则分成两个部分,递归集合最小点距。

已知两个集合内的最小点距,把与中点x距离小于最小点距的点放入容器中。

根据y排序,对于每两个y距离小于最小点距的两个点求距离,更新最小点距。

设计(核心代码):

 1 double getMin(int l, int r)
 2 {
 3     if (l == r)    return inf;
 4     if (r - l == 1)  return dis(p[r], p[l]);
 5     if (r - l == 2)
 6     {
 7         double d1, d2, d3;
 8         d1 = dis(p[l], p[l + 1]);
 9         d2 = dis(p[l], p[r]);
10         d3 = dis(p[l + 1], p[r]);
11         return min(d1, min(d2, d3));
12     }
13     int mid = l + r >> 1;
14     double dl, dr;
15     dl = getMin(l, mid);
16     dr = getMin(mid + 1, r);
17     double res = min(dl, dr);
18     vector<int>vec;
19     for (int i = l; i <= mid; ++i)
20     {
21         if (p[mid + 1].x - p[i].x <= res)  vec.push_back(i);
22     }
23     for (int i = mid + 1; i <= r; ++i)
24     {
25         if (p[i].x - p[mid].x <= res)    vec.push_back(i);
26     }
27     sort(vec.begin(), vec.end(), cmp2);
28     for (int i = 0; i < vec.size(); ++i)
29     {
30         for (int j = i + 1; j < vec.size(); ++j)
31         {
32             if (p[vec[j]].y - p[vec[i]].y <= res)
33             {
34                 res = min(res, dis(p[vec[i]], p[vec[j]]));
35             }
36             else break;
37         }
38     }
39     return res;
40 
41 }

分析:

复杂度:$O(nlogn)$。

源码:

https://github.com/Big-Kelly/Algorithm

  1 //#include<bits/stdc++.h>
  2 #include <set>
  3 #include <map>
  4 #include <stack>
  5 #include <cmath>
  6 #include <queue>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstring>
 11 #include <iostream>
 12 #include <algorithm>
 13 
 14 #define ll long long
 15 #define pll pair<ll,ll>
 16 #define pii pair<int,int>
 17 #define bug printf("*********\n")
 18 #define FIN freopen("input.txt","r",stdin);
 19 #define FON freopen("output.txt","w+",stdout);
 20 #define IO ios::sync_with_stdio(false),cin.tie(0)
 21 #define ls root<<1
 22 #define rs root<<1|1
 23 #define Q(a) cout<<a<<endl
 24 
 25 using namespace std;
 26 const int inf = 0x3f3f3f3f;
 27 const ll Inf = 1e18 + 7;
 28 const int maxn = 1e4 + 5;
 29 const int mod = 1e9 + 7;
 30 
 31 ll gcd(ll a, ll b)
 32 {
 33     return b ? gcd(b, a % b) : a;
 34 }
 35 
 36 ll lcm(ll a, ll b)
 37 {
 38     return a / gcd(a, b) * b;
 39 }
 40 
 41 ll read()
 42 {
 43     ll p = 0, sum = 0;
 44     char ch;
 45     ch = getchar();
 46     while (1)
 47     {
 48         if (ch == '-' || (ch >= '0' && ch <= '9'))
 49             break;
 50         ch = getchar();
 51     }
 52 
 53     if (ch == '-')
 54     {
 55         p = 1;
 56         ch = getchar();
 57     }
 58     while (ch >= '0' && ch <= '9')
 59     {
 60         sum = sum * 10 + ch - '0';
 61         ch = getchar();
 62     }
 63     return p ? -sum : sum;
 64 }
 65 
 66 struct node
 67 {
 68     int x, y;
 69 }p[maxn];
 70 
 71 bool cmp(const node& a, const node& b)
 72 {
 73     return a.x < b.x;
 74 }
 75 
 76 bool cmp2(const int& a, const int& b)
 77 {
 78     return p[a].y < p[b].y;
 79 }
 80 
 81 double dis(const node& a, const node& b)
 82 {
 83     double x = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
 84     return sqrt(x);
 85 }
 86 
 87 int n;
 88 
 89 double getMin(int l, int r)
 90 {
 91     if (l == r)    return inf;
 92     if (r - l == 1)  return dis(p[r], p[l]);
 93     if (r - l == 2)
 94     {
 95         double d1, d2, d3;
 96         d1 = dis(p[l], p[l + 1]);
 97         d2 = dis(p[l], p[r]);
 98         d3 = dis(p[l + 1], p[r]);
 99         return min(d1, min(d2, d3));
100     }
101     int mid = l + r >> 1;
102     double dl, dr;
103     dl = getMin(l, mid);
104     dr = getMin(mid + 1, r);
105     double res = min(dl, dr);
106     vector<int>vec;
107     for (int i = l; i <= mid; ++i)
108     {
109         if (p[mid + 1].x - p[i].x <= res)  vec.push_back(i);
110     }
111     for (int i = mid + 1; i <= r; ++i)
112     {
113         if (p[i].x - p[mid].x <= res)    vec.push_back(i);
114     }
115     sort(vec.begin(), vec.end(), cmp2);
116     for (int i = 0; i < vec.size(); ++i)
117     {
118         for (int j = i + 1; j < vec.size(); ++j)
119         {
120             if (p[vec[j]].y - p[vec[i]].y <= res)
121             {
122                 res = min(res, dis(p[vec[i]], p[vec[j]]));
123             }
124             else break;
125         }
126     }
127     return res;
128 
129 }
130 
131 int main()
132 {
133     scanf("%d", &n);
134     for (int i = 1; i <= n; ++i)
135     {
136         scanf("%d %d", &p[i].x, &p[i].y);
137     }
138     sort(p + 1, p + 1 + n, cmp);
139     printf("%.2f\n", getMin(1, n));
140 }
View Code

 

posted on 2020-03-30 22:10  Big-Kelly  阅读(125)  评论(0编辑  收藏  举报