• 最近点对学习笔记


    最近点对算法步骤

    1.先把所有点按照横坐标的关键字排序

    2.选取中线将点分成2份

    3.递归的求出左边部分的最近点距离d1,右边的最近点距离d2,取d=min(d1,d2)

    4.以中线为界,在左右2边d的范围内寻找点,看是否存在跨越中线的点距离小于d

    我们要注意的就是第四步,本来我们是需要n^2的时间,但是由于我们已经知道了左右的最近点距离,所以我们向左搜和向右搜的范围就大大减少了,而且,如果存在2个点的在我们搜的左右范围内,但是其2点的纵坐标之差大于d也可以直接排除了

    所以第三步的具体做法就出来啦......

    1."删除"所有到中线距离大于d的点.

    2.把一边平面内的点按照纵坐标排序

    3.对于另外一个平面内的点,找到其纵坐标的差在d以内的点,计算距离取min

     就是这样啦

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define FOR(i,a,b) for(register int i=a;i<=b;i++)
     4 #define ROF(i,a,b) for(register int i=a;i>=b;i--)
     5 using namespace std;
     6 int n;
     7 const ll N=1000000000000;
     8 int tmpt[200100];
     9 struct ss
    10 {
    11     double x;double y;
    12 }pot[200100];
    13 int scan()
    14 {
    15     int as=0,f=1;
    16     char c=getchar();
    17     while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
    18     while(c>='0'&&c<='9'){as=(as<<3)+(as<<1)+c-'0';c=getchar();}
    19     return as*f;
    20 }
    21 bool cmp(ss i,ss j)
    22 {
    23     return i.x<j.x;
    24 }
    25 bool cmp2(int i,int j)
    26 {
    27     return pot[i].y<pot[j].y;
    28 }
    29 double dis(int i,int j)
    30 {
    31     double f=sqrt(double((pot[i].x-pot[j].x)*(pot[i].x-pot[j].x)+(pot[i].y-pot[j].y)*(pot[i].y-pot[j].y)));
    32     return f; 
    33 }
    34 double par(int l,int r)
    35 {
    36 //    cout<<"y"<<endl;
    37     double d=N;
    38     if(l==r) return d;
    39     if(l+1==r) return dis(l,r);
    40     int mid=(l+r)>>1;//除以2
    41     double d1=par(l,mid);
    42     double d2=par(mid+1,r);
    43     d=min(d1,d2);
    44     int k=0;
    45     FOR(i,l,r)
    46     {
    47         if(abs(pot[i].x-pot[mid].x)<=d)
    48         {
    49             tmpt[++k]=i;//保存位置
    50         }
    51     }
    52     sort(tmpt+1,tmpt+k+1,cmp2);
    53     FOR(i,1,k)
    54     {
    55         FOR(j,i+1,k)
    56         {
    57             if(pot[tmpt[j]].y-pot[tmpt[i]].y>=d) break;
    58             double d3=dis(tmpt[i],tmpt[j]);
    59             d=min(d,d3);
    60         }
    61     }
    62     return d;
    63 }
    64 int main()
    65 {
    66 //    freopen("copy.in","r",stdin);
    67 //    freopen("copy.out","w",stdout);
    68     n=scan();
    69     FOR(i,1,n)
    70     {
    71         scanf("%lf%lf",&pot[i].x,&pot[i].y);
    72     }
    73     sort(pot+1,pot+n+1,cmp);
    74     double h=par(1,n);
    75     printf("%.4lf",h);//求1~n的最近点对
    76     return 0;
    77 }
    代码在这里
  • 相关阅读:
    oracle 当行函数 日期
    veridata实验举例(1)验证TCUSTMER与TCUSTORD两节点同步情况
    sdut1730 数字三角形问题(dp入门题)
    Android4.0 Design之UI设计易犯的错误2
    怎样提高团队管理能力6
    Effective C++ 29-33
    内存补齐序列一:关于内存对齐和填充
    【 D3.js 入门系列 --- 10.1 】 简化 GeoJSON 文件
    Android TrafficStats类的使用
    新手上路:Laravel-控制器基础
  • 原文地址:https://www.cnblogs.com/KSTT/p/10363076.html
Copyright © 2020-2023  润新知