平面二维点对最短距离求解问题

二维点对,先随机生成平面点,再把平面上的点划分成左右两部分,我觉得其实无所谓左右点的多少,对结果没有影响,记录最短距离的点,比较中线附近的点的距离。

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
using namespace std;
const double INF = 1e20;//相当于正无穷
const int N =10000;
struct Point
{
	double x, y;//二维点的横纵坐标
	
}point[N];
int tmpt[N];
void setpoints(Point point[], int num);
float dis(int a, int b);
void paixu1(Point L[], int num);
double min(double a, double b);
double Closest_Pair(int left, int right, Point &p, Point &q);

int main()
{
	int num;
	cout << "输入点的个数:";
	cin >> num;
	Point p, q;//距离最近的两个点``
	setpoints(point, num);//创造散点
	cout << "用分治法求最近对:" << endl;
	cout << "对散点的x进行排序:" << endl;
	paixu1(point, num);//x排序
	cout << endl << endl;
	double d;
	//DivideConquer( 0,num-1);

	d = Closest_Pair(0, num - 1,p,q); 
	cout << "距离最近的两点为:" << "(" << p.x << "," << p.y << ")" << "与" << "(" << q.x << "," << q.y << ")";
	//cout << "距离最近的两点为:" << "(" << point[p].x << "," << point[p].y << ")" << "与" << "(" << point[q].x << "," << point[q].y << ")";
	cout << "两点之间的最短距离为:" << sqrt(d) << endl;
	system("pause");
	return 0;

}
void setpoints(Point point[], int num)
{
	for (int i = 0; i < num; i++)

	{
		point[i].x = (rand() % 201-100) ;
		point[i].y = (rand() % 201-100 );
	}
	for (int i = 0; i < num; i++)
	{
		cout << "第" << i + 1 << "个点的坐标" << "(" << point[i].x << "," << point[i].y << ")" ;
		if ((i + 1) % 5 == 0) cout << endl;

	}
}
//求两点的距离的平方
float dis(int a, int b)
{
	return (point[a].x - point[b].x)*(point[a].x - point[b].x) + (point[a].y - point[b].y)*(point[a].y - point[b].y);
}
void paixu1(Point L[], int num)
{
	float t, m;	
	for (int i = 0; i < num; i++)
	{
		for (int j = 0; j < num - i - 1; j++)
		{
			if (L[j].x >L[j + 1].x)
			{
				t = L[j].x; m = L[j].y;
				L[j].x = L[j + 1].x; L[j].y = L[j + 1].y;
				L[j + 1].x = t; L[j + 1].y = m;
			}
		}		
	}
	cout << endl;
	for (int i = 0; i < num; i++)
	{
	cout << "第" << i + 1 << "个点的坐标" << "(" <<L[i].x << "," << L[i].y << ")";
	//min = L[0].x; max = L[num - 1].x;
	if ((i + 1) % 5 == 0) cout << endl;
	}
}

bool cmpy(const int& a, const int& b)

{

	return point[a].y < point[b].y;

}
double min(double a, double b)

{

	return a < b ? a : b;

}

double Closest_Pair(int left, int right,Point &p,Point &q)

{

double d = INF;

if (left == right)

{
	return d;
	
}

if (left + 1 == right)

	return dis(left, right);

int mid = (left + right) /2;

double d1 = Closest_Pair(left, mid,p,q);//随着调用mid,left right 都在改变
Point d1p = p;
Point d1q = q;//保存左支最近两个点的点数据
double d2 = Closest_Pair(mid + 1, right,p,q);//得到右支的最短距离点数据

d = min(d1, d2);
if (d1 < d2) {
	d = d1;
	p = d1p;
	q = d1q;
}
else {  //此时并不需要更新p,q的值,因为此时p和q的值就是右支的最小的一对点的坐标
	d= d2;
}

int i, j, k = 0;

//分离出宽度为d的区间

for (i = left; i <= right; i++)

{

	if (fabs(point[mid].x - point[i].x) <= d)//fabs求绝对值函数,记录在中点左右两边距离中点坐标小于左右两边最小距离的点的个数
		tmpt[k++] = i;

}

sort(tmpt, tmpt + k, cmpy);//排序函数,(首地址,尾地址,排序方式)
for (i = 0; i < k; i++)

{

	for (j = i + 1; j < k && point[tmpt[j]].y - point[tmpt[i]].y<d; j++)

	{

		double d3 = dis(tmpt[i], tmpt[j]);

		if (d > d3)


		{
			d = d3;
			p.x = point[tmpt[i]].x; p.y = point[tmpt[i]].y;
			q.x = point[tmpt[j]].x; q.y = point[tmpt[j]].y;
		}
		

	}

}

return d;

}
希望我的代码对你的学习有帮助

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值