青训82题和259题目解析和感悟

111 阅读5分钟

数值操作的期望计算

小R有两个正整数aa和bb,她将随机选择其中一个数并将其乘以22。这个操作会进行两次,操作后的两个数之和会有所变化。小R想知道,操作结束后,两个数之和的期望值是多少?

例如:如果 a=3a=3 和 b=3b=3,那么有 1/21/2 的概率两数之和为 1212,1/21/2 的概率两数之和为 1515。因此,期望值为 13.513.5。


测试样例

样例1:

输入:a = 3 ,b = 3
输出:'13.50'

样例2:

输入:a = 5 ,b = 7
输出:'27.00'

样例3:

输入:a = 1 ,b = 1
输出:'4.50'

代码实现

def solution(a: int, b: int) -> str:
    # 期望值公式 
    expected_value = 9 * (a + b) / 4
    return f"{expected_value:.2f}"

if __name__ == '__main__':
    print(solution(3, 3) == '13.50')  
    print(solution(5, 7) == '27.00')  
    print(solution(1, 1) == '4.50')
    

思路解析

  1. 操作过程

    • 首先,选择 a 或 b 之一进行乘以 2 操作。假设这个操作结束后我们得到了新的两个数 a' 和 b'
    • 该操作会随机进行两次,因此最终的结果会受到每次选择的影响。
  2. 计算期望值的基本思路

    • 假设初始状态为 (a, b)

    • 第一次选择:

      • 以 1/2 的概率选择 a 或者选择 b。选择 a 时,a 变为 2a,选择 b 时,b 变为 2b
    • 第二次选择:

      • 选择的规则与第一次相同,随机选择一个数并将其乘以 2
  3. 状态转移

    • 在两次操作后,可能的结果有四种组合:

      1. 第一次选 a,第二次选 a:即 (2a, 2b)
      2. 第一次选 a,第二次选 b:即 (2a, 2b)
      3. 第一次选 b,第二次选 a:即 (2a, 2b)
      4. 第一次选 b,第二次选 b:即 (2a, 2b)
  4. 期望值计算

    • 由于我们随机选择两次操作,因此期望值就是以下组合的平均值:

公式推导:

对于上述情况,可以将得到的 ab 进行求平均

小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 个备选的火车站位置。

如果有多个火车站最优,那么选择第一次出现的那个。


测试样例

样例1:

输入:n = 4,m = 3,citizens = [[-1, -1], [-1, 1], [1, -1], [1, 1]],locations = [[3, 2], [1, 0], [0, 0]]
输出:[1, 0]

样例2:

输入:n = 2,m = 2,citizens = [[0, 0], [0, 4]],locations = [[0, 2], [0, 3]]
输出:[0, 2]

样例3:

输入:n = 3,m = 1,citizens = [[10, 10], [20, 20], [30, 30]],locations = [[15, 15]]
输出:[15, 15]

样例4:

输入:n = 5,m = 3,citizens = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]],locations = [[4, 5], [6, 7], [8, 9]]
输出:[4, 5]

样例5:

输入:n = 6,m = 2,citizens = [[10, 10], [20, 20], [30, 30], [40, 40], [50, 50], [60, 60]],locations = [[35, 35], [45, 45]]
输出:[35, 35]

    # 初始化最小总旅行时间和最优火车站的位置
    min_distance = float('inf')
    best_location = None
    
    # 遍历所有备选的火车站位置
    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

  1. 曼哈顿距离: 曼哈顿距离公式是: [ \text{distance}(x_1, y_1, x_2, y_2) = |x_1 - x_2| + |y_1 - y_2| ] 其中,((x_1, y_1)) 是市民的坐标,((x_2, y_2)) 是备选的火车站坐标。这个距离反映了在网格状的城市街道上,从一个位置到另一个位置的最短路径。

  2. 目标: 选出一个备选火车站,使得所有市民到这个火车站的曼哈顿距离之和最小。

  3. 计算步骤

    • 对每个备选位置(假设为 ([p, q])),我们需要计算所有市民到这个位置的曼哈顿距离之和。
    • 对比每个位置的总距离,选择最小的那个。
  4. 细节

    • 如果多个位置的总距离相同,我们选择第一个出现的备选位置。
    • 由于每个火车站的位置只需要遍历一次所有市民,因此时间复杂度为 (O(n \times m)),其中 (n) 是市民数量,(m) 是备选火车站的位置数量。

解决方案的步骤

  1. 初始化一个变量 min_distance 来记录当前最小的总距离,将其设置为一个非常大的数。
  2. 初始化 best_location 来记录最优位置的坐标。
  3. 遍历所有备选的火车站位置,对每个位置计算所有市民到这个位置的曼哈顿距离之和。
  4. 如果某个备选位置的总曼哈顿距离小于当前的最小值,就更新最小值和最优位置。
  5. 最终返回最优的火车站位置。