标签:
---恢复内容开始---
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 47126 Accepted Submission(s): 12323
这个题目其实就是求最近点对的距离。《算法导论》上有详细讲解,王晓东的书上也有代码。主要思想就是分治。先把n个点按x坐标排序,然后求左边n/2个和右边n/2个的最近距离,最后合并。
合并要重点说一下,比较麻烦。
首先,假设点是n个,编号为1到n。我们要分治求,则找一个中间的编号m,先求出1到m点的最近距离设为d1,还有m+1到n的最近距离设为d2。这里的点需要按x坐标的顺序排好,并且假设这些点中,没有2点在同一个位置。(若有,则直接最小距离为0了)。
然后,令d为d1, d2中较小的那个点。如果说最近点对中的两点都在1-m集合中,或者m+1到n集合中,则d就是最小距离了。但是还有可能的是最近点对中的两点分属这两个集合,所以我们必须先检测一下这种情况是否会存在,若存在,则把这个最近点对的距离记录下来,去更新d。这样我们就可以得道最小的距离d了。
关键是要去检测最近点对,理论上每个点都要和对面集合的点匹配一次,那效率还是不能满足我们的要求。所以这里要优化。怎么优化呢?考虑一下,假如以我们所选的分割点m为界,如果某一点的横坐标到点m的横坐标的绝对值超过d1并且超过d2,那么这个点到m点的距离必然超过d1和d2中的小者,所以这个点到对方集合的任意点的距离必然不是所有点中最小的。(上面的是噢别人的,链接http://blog.csdn.net/allenjy123/article/details/6627751)
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<queue> 5 #include<string.h> 6 #include<stdlib.h> 7 #include<set> 8 #include<math.h> 9 using namespace std; 10 const double INF=1e12; 11 typedef struct pp 12 { 13 double x; 14 double y; 15 } ss; 16 bool cmp_x(pp p,pp q) 17 { 18 return p.x < q.x; 19 } 20 bool cmp_y(pp p,pp q) 21 { 22 return p.y < q.y; 23 } 24 double slove(pp *s,int m); 25 ss node[1000005]; 26 int main(void) 27 { 28 int i,j; 29 int n;int __ca=0; 30 while(scanf("%d",&n),n != 0) 31 { 32 for(i = 0; i < n; i++) 33 { 34 scanf("%lf %lf",&node[i].x,&node[i].y); 35 } 36 sort(node,node+n,cmp_x); 37 double ask = slove(node,n); 38 printf("%.2f\n",ask/2); 39 } 40 return 0; 41 } 42 double slove(ss *s,int m) 43 { 44 if(m <= 1)return INF; 45 int mid = m/2; 46 double d;int x = s[mid].x; 47 d = min(slove(s,mid),slove(s+mid,m-mid)); 48 inplace_merge(s,s+mid,s+m,cmp_y); 49 int i,j; 50 vector<ss>vec; 51 for(i = 0;i < m; i++) 52 { 53 if(fabs(s[i].x-x) >= d) 54 continue; 55 int cn = vec.size(); 56 for(j = 0;j < cn ;j++) 57 { 58 double dx = fabs(s[i].x - vec[cn-j-1].x); 59 double dy = fabs(s[i].y - vec[cn-j-1].y); 60 if(dy >= d) 61 break; 62 d = min(d,sqrt(dx*dx+dy*dy)); 63 } 64 vec.push_back(s[i]); 65 } 66 return d; 67 }
标签:
原文地址:http://www.cnblogs.com/zzuli2sjy/p/5796253.html