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 }
    代码在这里
  • 相关阅读:
    PAT B1027 打印沙漏 (20 分)
    PAT B1025 反转链表 (25 分)
    PAT B1022 D进制的A+B (20 分)
    PAT B1018 锤子剪刀布 (20 分)
    PAT B1017 A除以B (20 分)
    PAT B1015 德才论 (25 分)
    PAT B1013 数素数 (20 分)
    PAT B1010 一元多项式求导 (25 分)
    HDU 1405 The Last Practice
    HDU 1165 Eddy's research II
  • 原文地址:https://www.cnblogs.com/KSTT/p/10363076.html
Copyright © 2011-2022 走看看