最近点对学习笔记

最近点对算法步骤

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 }
代码在这里

猜你喜欢

转载自www.cnblogs.com/KSTT/p/10363076.html