算法导论复习(四)| 平面最近点对

文章描述了一个使用分治法解决平面上n个点间最近点对查找的问题,通过递归分割点集并暴力求解跨越分割线的点对,时间复杂度为O(nlogn)。给出了C++代码实现,包括点结构定义、排序和分治函数mergenode()的描述。
摘要由CSDN通过智能技术生成

问题描述

已知平面上分布着点集P中的n个点p1,p2,…pn,点i的坐标记为(xi,yi),1≤i≤n。两点之间的距离取其欧式距离。

问题:找出一对距离最近的点。


算法步骤

采用分治法

记, dL:PL中的最近点对距离;dR:PR中的最近点对距离;dC:跨越分割线的最近点对距离

  • 做分割线(垂线)将点集分为PL和PR两部分
  • 递归地在PL中的找具有dL的点对
  • 递归地在PR中的找具有dR的点对
  • 在跨越分割线的点对中找具有dC的点对
  • 返回min(dL,dR,dC)对应的点对。

主要思想:
1
在考虑跨越分割线时注意7个点:
2
对坐标排序导致O(nlog2n)时间复杂度的改进:
3
4


算法实现

贴一份O(nlogn)的算法(实在不会写了QAQ):

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int n;
struct node{
	double x,y;
}p[200005],q[200005];

bool cmp(node a,node b){
	return a.x<b.x;
}

double mergenode(int l,int r)
{
	if(l==r)
		return 100000000.0;	
	int mid=(l+r)>>1;
	double ans=min(mergenode(l,mid),mergenode(mid+1,r)); //分治
	int cnt=0;
	for(int i=l;i<=r;++i) 
		if(fabs(p[i].x-p[mid].x)<ans)
			q[++cnt]=p[i];
	for(int i=1;i<cnt;++i) //暴力求解跨越分割线的点
		for(int j=i+1;j<=cnt;++j) 
			ans=min(ans,sqrt((q[i].x-q[j].x)*(q[i].x-q[j].x)+(q[i].y-q[j].y)*(q[i].y-q[j].y)));
	return ans;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
		scanf("%lf%lf",&p[i].x,&p[i].y);
	sort(p+1,p+n+1,cmp); //排序预处理
	printf("%.4lf",mergenode(1,n));
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值