问题描述
小F是A市的市长,正在计划在A市新建一个火车站以方便市民的日常出行。市区内的街道布局十分规整,形成网格状。从一个位置[x1, y1]到另一个位置[x2, y2]的距离计算方法为 |x1 - x2| + |y1 - y2|,即曼哈顿距离。
在初步考察后,市政府列出了M个可能的火车站建设点。为了使得市民到火车站的总旅行时间最短,小F希望选出一个最优位置作为火车站的地址。
请你帮助小F计算出哪一个位置最适合建设新火车站。
N: 市民的总人数。 M: 可建设火车站的备选位置数。
citizens: 一个列表,每个元素是一个元组 [x_i, y_i],表示第 i 位市民的居住位置。 locations: 一个列表,每个元素是一个元组 [p_i, q_i],表示第 i 个备选的火车站位置。
如果有多个火车站最优,那么选择第一次出现的那个。
思路分析
对每个候选位置计算所有市民到该位置的总曼哈顿距离,最终选择总距离最小的位置。
算法步骤
-
初始化最小距离与最佳位置:
- 使用一个变量
min_distance来存储当前找到的最小总距离,初始值设定为正无穷。 - 使用一个变量
best_location来保存最佳位置,初始位置设为[-1, -1]。
- 使用一个变量
-
遍历候选火车站位置:
- 对每个候选位置进行迭代,计算所有市民到该位置的总曼哈顿距离。
-
计算曼哈顿距离:
- 对于每位市民,使用曼哈顿距离公式
|x_i - p| + |y_i - q|来计算市民到当前候选位置的距离。 - 将这些距离累加,得到当前候选位置到所有市民的总距离。
- 对于每位市民,使用曼哈顿距离公式
-
更新最优位置:
- 如果当前候选位置的总距离小于之前记录的最小距离,则更新
min_distance和best_location。
- 如果当前候选位置的总距离小于之前记录的最小距离,则更新
-
返回结果:
- 在遍历完所有候选位置后,返回
best_location。
- 在遍历完所有候选位置后,返回
代码实现
def solution(n, m, citizens, locations):
# Please write your code here
# 初始化最小总距离为正无穷,最优位置为空
min_distance = float('inf')
best_location = [-1, -1]
# 遍历每一个候选火车站位置
for loc in locations:
total_distance = 0
# 对于每位市民,计算到该位置的曼哈顿距离
for citizen in citizens:
total_distance += abs(citizen[0] - loc[0]) + abs(citizen[1] - loc[1])
# 如果当前总距离小于已知最小距离,则更新最小距离和最优位置
if total_distance < min_distance:
min_distance = total_distance
best_location = loc
return best_location
# return [-1, -1]
if __name__ == "__main__":
# You can add more test cases here
citizens1 = [[-1, -1], [-1, 1], [1, -1], [1, 1]]
locations1 = [[3, 2], [1, 0], [0, 0]]
print(solution(4, 3, citizens1, locations1) == [1, 0])
知识点总结
-
曼哈顿距离:在城市网格布局中,用于计算两个点之间的距离。公式是
|x1 - x2| + |y1 - y2|。 -
算法复杂度:
- 此算法的时间复杂度是O(M * N),其中M是候选位置的数量,N是市民的数量。对于大规模输入,可能需要考虑更高效的解法。
-
选择最优解:在有多个最优解存在的情况下,选择第一次出现的解,可以通过在遍历时继续记录而不是返回最后的更新来实现。