• 实验5最近对问题


    问题:

    对$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("*********
    ")
     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
    ", getMin(1, n));
    140 }
    View Code
  • 相关阅读:
    结对编程的理解
    第1章 python基础
    第 3 章 前端基础之JavaScript
    第1 章 mysql数据库之简单的DDL和DML sql语句
    第 1 章 前端之html
    第 13 章 python并发编程之io模型
    第 2 章 前端基础之CSS
    第 4 章 前端基础之jquery
    第 11 章 python线程与多线程
    注册表 SAM
  • 原文地址:https://www.cnblogs.com/zhang-Kelly/p/12601681.html
Copyright © 2020-2023  润新知