卡牌翻面求和问题 | 豆包MarsCode AI刷题

130 阅读2分钟

卡牌翻面求和问题|豆包MarsCode AI刷题

问题描述

小M有n张卡牌,每张卡牌的正反面分别写着不同的数字,正面是a_i,背面是b_i。小M希望通过选择每张卡牌的一面,使得所有向上的数字之和可以被3整除。你需要告诉小M,一共有多少种不同的方案可以满足这个条件。由于可能的方案数量过大,结果需要对10^9+7取模。

例如:如果有3张卡牌,正反面数字分别为(1,2),(2,3)和(3,2),你需要找到所有满足这3张卡牌正面或背面朝上的数字之和可以被3整除的组合数。

测试样例

样例1: 输入:x_position = 12, y_position = 6 输出:4

样例2: 输入:x_position = 34, y_position = 34 输出:6

样例1: 输入:x_position = 50, y_position = 30 输出:8

样例1: 输入:x_position = 0, y_position = 0 输出:0

题目分析

题目大意是:

  1. 有n张卡牌,每张卡牌有正反两面,正面数字为a[i],反面数字为b[i]。
  2. 需要找到所有卡牌的正反面数字中符合条件的组合,使得这些组合的数字之和可以被 3 整除。
  3. 输出满足该条件的组合数。
  4. 输出结果需对10^9+7取模。

解题思路

  • 组合生成:每张卡牌可以选择正面或反面,因此对于n张卡牌,总共有2^n种组合。

  • 满足条件的组合:遍历所有组合,检查组合和是否可以被 3 整除。

  • 取模:将结果对10^9+7取模以防止溢出。

实现代码

以下是python的解法代码:

MOD = 10**9 + 7

def solution(n: int, a: list, b: list) -> int:
    # 用来计数符合条件的组合数量
    count = 0
    
    # 通过二进制枚举所有组合情况
    for mask in range(1 << n):
        total = 0
        for i in range(n):
            # 根据 mask 的每一位选择正面或反面
            if mask & (1 << i):
                total += a[i]  # 选择 a[i](正面)
            else:
                total += b[i]  # 选择 b[i](反面)
        
        # 检查组合和是否能被3整除
        if total % 3 == 0:
            count += 1

    return count % MOD

# 测试样例
if __name__ == '__main__':
    print(solution(n = 3, a = [1, 2, 3], b = [2, 3, 2]) == 3)
    print(solution(n = 4, a = [3, 1, 2, 4], b = [1, 2, 3, 1]) == 6)
    print(solution(n = 5, a = [1, 2, 3, 4, 5], b = [1, 2, 3, 4, 5]) == 32)

解释

  • 使用二进制数mask枚举所有组合可能性。
  • total 变量用于计算组合中选取的数字之和。
  • 判断是否满足整除3的条件,如果满足,计数加一。
  • 最后返回计数对10^9+7取模的结果