zoukankan      html  css  js  c++  java
  • 最近点对学习笔记

    最近点对算法步骤

    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 }
    代码在这里
  • 相关阅读:
    算法第二章上机实践报告
    算法第一章作业
    第7章学习小结 不使用STL-map过实践题:QQ帐户的申请与登陆
    第6章学习小结
    HDU
    HDU 2089 不要62(数位DP)
    char-2
    chart-7
    chart-6
    char-8
  • 原文地址:https://www.cnblogs.com/KSTT/p/10363076.html
Copyright © 2011-2022 走看看