Bootstrap

利用 Python 解决 “Rudolf and the Ticket” 问题

利用 Python 解决 “Rudolf and the Ticket” 问题

一、问题描述

在 “Rudolf and the Ticket” 这个情境中,Rudolf 打算乘坐地铁去拜访 Bernard,需要在一台只接受两枚硬币且两枚硬币总和不超过 k 的机器上购买车票。Rudolf 有两个口袋放着硬币,左边口袋有 n 枚硬币,面值分别为 b1, b2, …, bn;右边口袋有 m 枚硬币,面值分别为 c1, c2, …, cm。任务就是帮助 Rudolf 确定从两个口袋中各选一枚硬币(总共两枚硬币),使得它们面值之和不超过 k 的选择方式有多少种。

输入要求

输入的第一行包含一个整数 t(满足 1≤t≤100),它代表测试用例的数量。接下来对每个测试用例进行描述:

  • 每个测试用例的第一行包含三个自然数 nm 和 k(满足 1≤n, m≤1001≤k≤2000),分别表示左边口袋硬币数量、右边口袋硬币数量以及购买车票时两枚硬币总和的最大值。
  • 每个测试用例的第二行包含 n 个整数 bi(满足 1≤bi≤1000),代表左边口袋硬币的面值。
  • 每个测试用例的第三行包含 m 个整数 ci(满足 1≤ci≤1000),代表右边口袋硬币的面值。

输出要求

对于每一个测试用例,输出一个整数,即 Rudolf 能从两个口袋中各选一枚硬币,使得硬币总和不超过 k 的选择方式的数量。

以下是一些输入输出的示例帮助理解:

输入示例

收起

plaintext

4
4 4 8
1 5 10 14
2 3 4 8
2 3 4
1 2
4 2 7
1 1 1 1
2 7
3 4 2000
1 1 1
1 1 1 1

输出示例

收起

plaintext

6
0
4
12

具体说明示例情况如下

  • 在第一个测试用例中,Rudolf 可以选择的硬币组合为 [1,1][1,2][1,4][2,1][2,2][2,4] 这些对应的索引组合(注意这里是索引,并非面值本身)。
  • 在第二个测试用例中,从两个口袋中任取一枚硬币,它们的面值之和都会超过 k = 4,所以没有满足条件的选择方式,输出为 0
  • 在第三个测试用例中,Rudolf 可以选择的组合为 [1,1][2,1][3,1][4,1]
  • 在第四个测试用例中,Rudolf 从左边口袋任取一枚硬币和右边口袋任取一枚硬币的组合都满足条件,共存在 12 种满足要求的组合方式。

二、Python 代码实现

以下是使用 Python 语言编写的用于解决该问题的代码:

收起

python

def count_pairs(n, m, k, left_coins, right_coins):
    count = 0
    for b in left_coins:
        for c in right_coins:
            if b + c <= k:
                count += 1
    return count

def main():
    t = int(input())  # 读取测试用例数量
    results = []

    for _ in range(t):
        # 读取 n, m, k
        n, m, k = map(int, input().split())
        # 读取左口袋的硬币
        left_coins = list(map(int, input().split()))
        # 读取右口袋的硬币
        right_coins = list(map(int, input().split()))
        
        # 计算满足条件的配对数
        results.append(count_pairs(n, m, k, left_coins, right_coins))
    
    # 输出所有结果
    print("\n".join(map(str, results)))

if __name__ == "__main__":
    main()

代码详细说明

  1. count_pairs 函数

    • 输入参数
      • n:代表左口袋的硬币数量。
      • m:代表右口袋的硬币数量。
      • k:表示两枚硬币和的最大值限制。
      • left_coins:是一个包含左口袋硬币面值的数组。
      • right_coins:是一个包含右口袋硬币面值的数组。
    • 逻辑流程:通过两层循环,外层循环遍历左口袋的每一枚硬币(用 b 表示其面值),内层循环遍历右口袋的每一枚硬币(用 c 表示其面值),对于每一种左右口袋硬币的组合,检查它们的面值之和是否小于等于 k,如果满足该条件,就将计数器 count 的值加 1,最终返回这个计数器的值,也就是满足条件的组合数量。
  2. main 函数

    • 首先读取输入的测试用例数量 t,并初始化一个空列表 results,用于存放每个测试用例的计算结果。
    • 然后针对每一个测试用例:
      • 先读取 nmk 的值,接着分别读取左口袋和右口袋的硬币面值数组 left_coins 和 right_coins
      • 调用 count_pairs 函数来计算该测试用例中满足条件的硬币配对数,并将结果添加到 results 列表中。
    • 最后通过 print("\n".join(map(str, results))) 将列表中的结果逐行输出,使得每个测试用例的结果各占一行。

三、复杂度分析

对于每一个测试用例而言,在 count_pairs 函数中存在两层循环,外层循环遍历 n 次,内层循环遍历 m 次,所以时间复杂度是 O(n * m),其中 n 和 m 分别是左右口袋硬币数组的长度。而总时间复杂度取决于输入的测试用例数量以及每个测试用例中硬币数组的规模大小。

希望通过本文能让大家清晰理解 “Rudolf and the Ticket” 问题以及对应的 Python 解决思路与代码实现细节,方便大家在遇到类似问题时进行参考和应用。

你可以根据实际需求对文章内容进行适当调整、润色或者添加更多个性化的内容,使其更加完善且符合自己的分享目的。

;