中等题:理想火车站定位

3 阅读5分钟

理想火车站定位

问题描述

小F是A市的市长,正在计划在A市新建一个火车站,以方便市民的日常出行。市区内的街道布局十分规整,形成网格状。从一个位置 [x_1, y_1] 到另一个位置 [x_2, y_2] 的距离计算方法为 |x_1 - x_2| + |y_1 - y_2|,即曼哈顿距离。

在初步考察后,市政府列出了 M 个可能的火车站建设点。为了使得市民到火车站的总旅行时间最短,小F希望选出一个最优位置作为火车站的地址。

给定市民的总人数 N,可建设火车站的备选位置数 M,市民的坐标列表 citizens 和备选火车站的位置列表 locations,我们的任务是找到一个最优的火车站位置,使得所有市民到达火车站的曼哈顿距离之和最小。如果有多个火车站最优,则选择第一次出现的那个。

思路解析

本问题的核心在于计算每个备选火车站位置到所有市民的曼哈顿距离之和。由于曼哈顿距离的计算相对简单,我们可以采用暴力算法,逐一计算每个备选火车站位置到所有市民的距离。具体思路如下:

  1. 初始化变量:设置一个变量 min_total_distance 为正无穷大,用于记录当前的最小距离;设置 best_locationNone,用于记录最优位置。

  2. 遍历备选位置:对于每一个备选位置,初始化 total_distance 为 0,计算该位置到所有市民的曼哈顿距离之和。

  3. 计算距离:使用嵌套循环遍历每个市民,计算当前备选位置到每个市民的曼哈顿距离,并累加到 total_distance

  4. 更新最优位置:如果当前备选位置的总距离小于之前的最小距离,则更新 min_total_distancebest_location

  5. 返回结果:遍历完成后,返回 best_location

步骤

  1. 输入参数:接受市民数量 N、备选位置数量 M、市民坐标列表 citizens 和备选火车站坐标列表 locations

  2. 初始化最小距离和最佳位置min_total_distance 初始化为无穷大,best_location 初始化为 None

  3. 遍历所有备选位置

    • 对于每个备选位置,初始化 total_distance 为 0。
    • 遍历每个市民,计算其与当前备选位置的曼哈顿距离,并将其累加到 total_distance
  4. 更新最优位置:比较 total_distancemin_total_distance,如果小于,则更新 min_total_distancebest_location

  5. 输出最佳位置:返回找到的最佳位置。

代码详解

以下是实现上述思路的 Python 代码:

def solution(n, m, citizens, locations):
    min_total_distance = float('inf')  # 初始化为正无穷大
    best_location = None  # 最优位置初始化

    # 遍历每一个备选位置
    for location in locations:
        total_distance = 0  # 当前备选位置的总距离
        # 计算当前备选位置到所有市民的曼哈顿距离之和
        for citizen in citizens:
            total_distance += abs(location[0] - citizen[0]) + abs(location[1] - citizen[1])
        
        # 如果当前总距离小于最小距离,则更新
        if total_distance < min_total_distance:
            min_total_distance = total_distance
            best_location = location
    
    return best_location if best_location is not None else [-1, -1]  # 返回最优位置

if __name__ == "__main__":
    # 测试样例
    citizens1 = [[-1, -1], [-1, 1], [1, -1], [1, 1]]
    locations1 = [[3, 2], [1, 0], [0, 0]]
    print(solution(4, 3, citizens1, locations1) == [1, 0])  # 输出: True

    citizens2 = [[0, 0], [0, 4]]
    locations2 = [[0, 2], [0, 3]]
    print(solution(2, 2, citizens2, locations2) == [0, 2])  # 输出: True

    citizens3 = [[10, 10], [20, 20], [30, 30]]
    locations3 = [[15, 15]]
    print(solution(3, 1, citizens3, locations3) == [15, 15])  # 输出: True

    citizens4 = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
    locations4 = [[4, 5], [6, 7], [8, 9]]
    print(solution(5, 3, citizens4, locations4) == [4, 5])  # 输出: True

    citizens5 = [[10, 10], [20, 20], [30, 30], [40, 40], [50, 50], [60, 60]]
    locations5 = [[35, 35], [45, 45]]
    print(solution(6, 2, citizens5, locations5) == [35, 35])  # 输出: True

代码分析

  1. 时间复杂度:该算法的时间复杂度为 O(N×M),其中 N 是市民数量,M 是备选位置数量。对于每个备选位置,我们需要遍历所有市民以计算距离。

  2. 空间复杂度:空间复杂度为 O(1),因为我们只使用了常量级别的额外空间来存储变量。

  3. 可扩展性:该算法易于扩展,可以轻松添加更多的市民或备选位置,而无需修改主要逻辑。

个人总结

通过本次问题的解决,我深刻理解了曼哈顿距离的计算及其在城市规划中的应用。选择合适的火车站位置不仅能减少市民的出行时间,还能提升城市的整体交通效率。在实现过程中,我也体会到了算法复杂度的重要性,尽量优化计算过程,以提高程序的执行效率。

本问题的解决方案简单而有效,适用于类似的城市规划问题。在实际应用中,可以将此算法扩展到更复杂的场景,例如考虑不同市民的出行频率、交通工具的不同等因素,以进一步优化火车站的位置选择。

通过这次实践,我认识到,虽然目前的解决方案已经能够满足基本需求,但在实际应用中,可能还需要考虑更多的实际因素,比如交通流量、城市发展规划等。未来我将继续探索更高效的算法和数据结构,以应对更复杂的城市规划问题。