C++解决n点最小距离问题

作者制作不易,关注、点赞、收藏一下吧!

1.平面直角坐标系

       在平面内画两条互相垂直,并且有公共原点的数轴。其中横轴为X轴,纵轴为Y轴。这样我们就说在平面上建立了平面直角坐标系,简称直角坐标系。( 百度百科 )

图1 平面直角坐标系 ( 图片来源: 网络 )

2.代码实现

2.1.计算距离公式

两点间直线距离的平方等于横坐标之差的平方加纵坐标之差的平方,即

L^2 = (x1 - x2)^2 + (y1 - y2)^2,

使用时将结果开平方即可。

2.2.代码

2.2.1.头文件和命名空间导入

我们需要用到iostream、cmath( 平方和平方根 )和iomanip( 保留小数 ): 

#include <iostream> // 导入头文件
#include <cmath>
#include <iomanip>
using namespace std; // 导入命名空间

2.2.2.创建点的结构体列表

// 创建点的结构体列表
struct point_list{
	int x;
	int y;
}point[1001]; // 设置最多存放1001个点

有关结构体可以看我的一片有关结构体的文章。

2.2.3.获取数据

// 获取点的数据
int point_num;
cin >> point_num; // 输入点的数量
for(int i = 1; i <= point_num; i++) // 把数据存入point_list
{
	cin >> point[i].x >> point[i].y;
}

2.2.4.循环枚举,进行计算

// 循环枚举,进行计算
long long min_s = 999999999999999999; // 初始化最小值( 或1e18等 )
for(int i = 1; i <= point_num; i++) // 循环第一个点
{
	for(int j = i + 1; j <= point_num; j++) // 循环第2个点
	{
		// 代入公式,计算距离
		long long s1 = pow(point[i].x - point[j].x, 2); // 或者long long s1 = (a[i].x - a[j].x, 2) * (a[i].x - a[j].x, 2);下同。
		long long s2 = pow(point[i].y - point[j].y, 2);
		long long s = s1 + s2;
		if(s < min_s)
		{
			min_s = s;
		}
	}
}

注: 这里不进行开方运算。

使用双层for循环遍历点,代入公式,获得两个点之间长度的平方。

2.2.5.输出结果

// 输出结果
cout << fixed << setprecision(3) << sqrt(min_s); // 结果保留3位小数

2.3.完整代码

#include <iostream> // 导入头文件
#include <cmath>
#include <iomanip>
using namespace std; // 导入命名空间

// 创建点的结构体列表
struct point_list{
	int x;
	int y;
}point[1001]; // 设置最多存放1001个点

int main() // 主函数
{
	// 获取点的数据
	int point_num;
	cin >> point_num; // 输入点的数量
	for(int i = 1; i <= point_num; i++) // 把数据存入point_list
	{
		cin >> point[i].x >> point[i].y;
	}
	
	// 循环枚举,进行计算
	long long min_s = 999999999999999999; // 初始化最小值( 或1e18等 )
	for(int i = 1; i <= point_num; i++) // 循环第一个点
	{
		for(int j = i + 1; j <= point_num; j++) // 循环第2个点
		{
			// 代入公式,计算距离
			long long s1 = pow(point[i].x - point[j].x, 2); // 或者long long s1 = (a[i].x - a[j].x, 2) * (a[i].x - a[j].x, 2);下同。
			long long s2 = pow(point[i].y - point[j].y, 2);
			long long s = s1 + s2;
			if(s < min_s)
			{
				min_s = s;
			}
		}
	}
	
	// 输出结果
	cout << fixed << setprecision(3) << sqrt(min_s); // 结果保留3位小数
	
	return 0; // 结束程序
}

2.4.示例结果

2.4.1.例1

输入 3 1 0 1 1 2 10:

图2

2.4.2.例2

输入 3 2 10 1 31 0 -10:

图3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值