经典问题之最近点对问题
来源:互联网 发布:暴风城先锋长戟数据 编辑:程序博客网 时间:2024/04/29 05:23
解决问题:在平面内有n个点,求两两之间的最短距离。
题解:
1.枚举点,打擂台。O(n^2)
2.分治。先按x坐标排序,以中位数画一条线,将平面分成两个部分,对两个左右部分分别处理,然后合并。
合并:设总区间d=min{左区间d,右区间d}划分左右之后,按照y的大小归并两个区间的点坐标,然后以d为上届,刷去一些点,对于剩下的点直接左右互相算距离,打擂台即可。效率经证明为O(nlog n).
参考程序:
#include<cstdio>#include<algorithm>#include<vector>#include<cmath>#define maxn 21000#define INF 0x7f7f7f7fusing namespace std;int n;struct Pair{int x,y;bool operator < (const Pair& rhs) const {return x<rhs.x;}}loc[maxn];bool cmp_y(Pair a,Pair b){return a.y<b.y;}double closeset_pair(Pair *a,int n){if (n<=1)return INF;int m=n/2;double x=a[m].x;double d=min(closeset_pair(a,m),closeset_pair(a+m,n-m));inplace_merge(a,a+m,a+n,cmp_y);vector<Pair> b;for (int i=0;i<n;i++){if (fabs(a[i].x-x)>=d)continue; for (int j=0;j<b.size();j++){double dx=a[i].x-b[b.size()-j-1].x;double dy=a[i].y-b[b.size()-j-1].y;if (dy>=d)break;d=min(d,sqrt(dx*dx+dy*dy));}b.push_back(a[i]);}return d;}int main(){scanf("%d",&n);for (int i=0;i<n;i++)scanf("%d%d",&loc[i].x,&loc[i].y);sort(loc,loc+n);printf("%f",closeset_pair(loc,n));return 0;}
0 0
- 经典问题之最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 最近点对问题
- 分治策略之最近点对问题
- JavaAPI之Type接口
- 判断一个数是否为回文数,字符串是否为回文字符串
- 递归和非递归方法实现斐波那契
- 字符串中查找子串
- 实现大数四则运算
- 经典问题之最近点对问题
- 一个数组实现两个栈
- 迷宫问题
- 派生控件的处理。
- 使用两个栈实现一个队列
- 使用两个队列实现一个栈
- 实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- 稀疏矩阵的压缩存储和转置
- 递归实现广义表