这道华为秋招编程题的核心是:在给定若干城市信号塔坐标的情况下,计算所有信号塔之间的最小欧几里得距离。题目要求我们处理二维平面上的点集,找出其中距离最近的两个点,并返回这个最小距离值。
从工程角度看,这个问题属于典型的"最近点对"问题(Closest Pair of Points Problem),在通信基站部署、物流网点规划、军事雷达布防等场景都有实际应用价值。比如在5G基站建设中,工程师需要确保基站间距满足信号覆盖要求,同时避免资源浪费。
最直观的解法是暴力枚举所有点对,计算它们的距离并记录最小值。对于n个点,需要计算C(n,2)=n(n-1)/2次距离,时间复杂度为O(n²)。当n较小时(如题目中的1≤n≤1000),这种解法在OJ系统中是可接受的。
但实际工程中,当n达到10⁵级别时,O(n²)的复杂度将无法承受。这就引出了更高效的解法需求。
经典的分治算法可以在O(nlogn)时间内解决问题,其核心思想是:
关键优化在于第5步:对于带状区域内的每个点,只需检查其后7个点即可,这保证了线性时间复杂度。这种算法虽然理论复杂,但在大规模数据下优势明显。
在实际笔试和工程中,我们需要考虑:
对于华为机试这类场景,通常n≤1000,暴力法完全够用且更稳妥。这也是大多数考生会选择暴力解的原因。
java复制import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] towers = new int[n][2];
for(int i=0; i<n; i++){
towers[i][0] = sc.nextInt();
towers[i][1] = sc.nextInt();
}
double minDist = Double.MAX_VALUE;
for(int i=0; i<n; i++){
for(int j=i+1; j<n; j++){
int dx = towers[i][0]-towers[j][0];
int dy = towers[i][1]-towers[j][1];
double dist = Math.sqrt(dx*dx + dy*dy);
if(dist < minDist){
minDist = dist;
}
}
}
System.out.printf("%.2f", minDist);
}
}
关键注意事项:
Double.MAX_VALUE初始化最小距离cpp复制#include <iostream>
#include <vector>
#include <cmath>
#include <limits>
#include <iomanip>
using namespace std;
int main() {
int n;
cin >> n;
vector<pair<int, int>> towers(n);
for(int i=0; i<n; ++i){
cin >> towers[i].first >> towers[i].second;
}
double min_dist = numeric_limits<double>::max();
for(int i=0; i<n; ++i){
for(int j=i+1; j<n; ++j){
int dx = towers[i].first - towers[j].first;
int dy = towers[i].second - towers[j].second;
double dist = sqrt(dx*dx + dy*dy);
if(dist < min_dist){
min_dist = dist;
}
}
}
cout << fixed << setprecision(2) << min_dist << endl;
return 0;
}
性能优化点:
python复制import math
n = int(input())
towers = [tuple(map(int, input().split())) for _ in range(n)]
min_dist = float('inf')
for i in range(n):
for j in range(i+1, n):
dx = towers[i][0] - towers[j][0]
dy = towers[i][1] - towers[j][1]
dist = math.sqrt(dx*dx + dy*dy)
if dist < min_dist:
min_dist = dist
print("{0:.2f}".format(min_dist))
Python特有优化:
text复制// 普通情况
3
0 0
1 1
2 2
// 输出:1.41
// 两点重合
2
0 0
0 0
// 输出:0.00
// 大坐标差
2
0 0
10000 10000
// 输出:14142.14
// 随机大数据
1000
<1000个随机坐标>
// 应能在1s内完成
在实际通信工程中,可能需要考虑:
此时暴力法将完全不可行,必须使用更高级的数据结构如kd-tree。
当n极大时(如百万级),可以:
这些方法能以精度换时间,适合实时性要求高的场景。
利用现代多核CPU或GPU:
对于超大规模数据,可将问题分解到集群处理。
在真实的华为机考环境中,解题速度与正确率同样重要。建议平时练习时给自己设定时间限制,培养时间管理意识。对于200分的题目,通常需要在30-40分钟内完成编码和测试。