问题描述
小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
题目分析
题目大意是:
- 有n张卡牌,每张卡牌有正反两面,正面数字为a[i],反面数字为b[i]。
- 需要找到所有卡牌的正反面数字中符合条件的组合,使得这些组合的数字之和可以被 3 整除。
- 输出满足该条件的组合数。
- 输出结果需对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取模的结果