理想火车站定位

110 阅读4分钟

问题描述

在这道题中,小F是A市的市长,他正在计划在A市新建一个火车站以方便市民的日常出行。市区内的街道布局十分规整,形成网格状。从一个位置 [x1,y1][x1, y1] 到另一个位置 [x2,y2][x2, y2] 的距离计算方法为 ∣x1−x2∣+∣y1−y2∣|x1 - x2| + |y1 - y2|,即曼哈顿距离。在初步考察后,市政府列出了 MM 个可能的火车站建设点。为了使得市民到火车站的总旅行时间最短,小F希望选出一个最优位置作为火车站的地址。

我们需要帮助小F计算出哪一个位置最适合建设新火车站。

思考过程

一、理解曼哈顿距离

首先需要明确曼哈顿距离的计算方法。也就是两点间的距离公式,曼哈顿距离定义为在二维网格中移动时,仅允许在水平和垂直方向上移动的距离。具体的计算公式为:

distance=∣x1−x2∣+∣y1−y2∣\text{distance} = |x1 - x2| + |y1 - y2|

二、确定问题的解决思路

为了找到最优的火车站建设位置,需要计算每个备选位置到所有市民位置的总曼哈顿距离,然后选择总距离最短的那个位置。具体的思路可以分为以下几个步骤:

  1. 初始化最小总距离和最佳位置

    • 使用一个变量 min_total_distance 来记录最小的总曼哈顿距离,初始值设为正无穷大(float('inf')),表示尚未找到合适的火车站位置。
    • 使用一个变量 best_location 来记录最佳的火车站位置,初始值设为 [-1, -1],表示尚未找到合适的火车站位置。
  2. 遍历每个备选位置

    • 对于每个火车站备选位置 loc,计算其到所有市民位置的总曼哈顿距离。
    • 使用嵌套循环,外层循环遍历每个备选位置,内层循环遍历每个市民位置。
  3. 更新最小总距离和最佳位置

    • 如果当前火车站位置的总距离小于 min_total_distance,则更新 min_total_distancebest_location
  4. 返回最佳位置

    • 返回计算出的最佳火车站位置。

三、代码实现

def solution(n, m, citizens, locations):
    min_total_distance = float('inf')
    best_location = [-1, -1]
    
    for loc in locations:
        total_distance = 0
        for citizen in citizens:
            total_distance += abs(loc[0] - citizen[0]) + abs(loc[1] - citizen[1])
        
        if total_distance < min_total_distance:
            min_total_distance = total_distance
            best_location = loc
    
    return best_location

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])

代码详细解释

函数定义

def solution(n, m, citizens, locations):
  • 函数 solution 接受四个参数:

    • n:市民总人数。
    • m:火车站备选位置数。
    • citizens:市民的位置列表,每个元素是一个元组 [x_i, y_i],表示第 i 位市民的居住位置。
    • locations:火车站的备选位置列表,每个元素是一个元组 [p_i, q_i],表示第 i 个备选的火车站位置。

初始化最小总距离和最佳位置

python

min_total_distance = float('inf')
best_location = [-1, -1]
  • 初始化变量 min_total_distance,初始值为正无穷大,表示尚未找到合适的火车站位置。
  • 初始化变量 best_location,初始值为 [-1, -1],表示尚未找到合适的火车站位置。

遍历每个备选位置

python

for loc in locations:
    total_distance = 0
    for citizen in citizens:
        total_distance += abs(loc[0] - citizen[0]) + abs(loc[1] - citizen[1])
  • 外层循环遍历每个备选位置 loc
  • 内层循环遍历每个市民位置 citizen,计算其到当前火车站位置的曼哈顿距离,并累加到 total_distance

更新最小总距离和最佳位置

python

if total_distance < min_total_distance:
    min_total_distance = total_distance
    best_location = loc
  • 如果当前火车站位置的总距离小于 min_total_distance,则更新 min_total_distancebest_location

复杂度分析

时间复杂度

  • 外层循环遍历 m 个备选位置,内层循环遍历 n 个市民位置。因此,时间复杂度为 O(m×n)O(m \times n)。

空间复杂度

  • 该算法使用了常数级别的额外空间,因此空间复杂度为 O(1)O(1)。

测试用例分析

测试用例1

python

citizens1 = [[-1, -1], [-1, 1], [1, -1], [1, 1]]
locations1 = [[3, 2], [1, 0], [0, 0]]
print(solution(4, 3, citizens1, locations1) == [1, 0])
  • 市民的位置为 [[-1, -1], [-1, 1], [1, -1], [1, 1]],火车站的备选位置为 [[3, 2], [1, 0], [0, 0]]。计算每个备选位置的总曼哈顿距离后,选择总距离最小的那个位置。

总结

通过上述思考过程和代码实现,我们成功解决了小F在A市新建火车站的问题。遍历所有备选位置,计算每个位置到所有市民位置的总曼哈顿距离,选择总距离最短的位置作为最佳火车站位置。

**