问题描述
小M面对一组从 1 到 9 的数字,这些数字被分成多个小组,并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。
numbers: 一个由多个整数字符串组成的列表,每个字符串可以视为一个数字组。小M需要从每个数字组中选择一个数字。
例如对于[123, 456, 789],14个符合条件的数为:147 149 158 167 169 248 257 259 268 347 349 358 367 369。
测试样例
样例1:
输入:
numbers = [123, 456, 789]
输出:14
样例2:
输入:
numbers = [123456789]
输出:4
样例3:
输入:
numbers = [14329, 7568]
输出:10
题解
代码
from functools import lru_cache
def solution(numbers):
# 将字符串列表转换为整数列表
groups = [list(map(int, str(number))) for number in numbers]
@lru_cache(None)
def count_even_sum(index, current_sum):
# 如果所有组都已经处理完
if index == len(groups):
# 检查当前和是否为偶数
return 1 if current_sum % 2 == 0 else 0
total_ways = 0
# 遍历当前组中的每个数字
for digit in groups[index]:
# 递归处理下一个组,并更新当前和
total_ways += count_even_sum(index + 1, current_sum + digit)
return total_ways
return count_even_sum(0, 0)
if __name__ == "__main__":
# 测试样例
print(solution([123, 456, 789]) == 14) # 输出: True
print(solution([14329, 7568]) == 10) # 输出: True
给定一组由数字组成的字符串列表,每个字符串代表一个数字组,从每个数字组中选择一个数字来组成一个新的数,并且这个新数的各位数字之和需要是偶数。我们需要计算出有多少种不同的选择方法可以达到这一目标。
代码解释
-
导入库:
from functools import lru_cache: 导入了lru_cache装饰器,用于缓存函数结果以提高性能。当函数被重复调用时,如果参数相同,则直接返回缓存的结果,而不是重新计算。
-
定义主函数:
def solution(numbers): 接受一个包含多个整数字符串的列表numbers。
-
转换输入数据:
groups = [list(map(int, str(number))) for number in numbers]: 将每个字符串转换成一个整数列表。例如,对于输入[123, 456, 789],groups将变成[[1, 2, 3], [4, 5, 6], [7, 8, 9]]。
-
定义递归函数:
@lru_cache(None): 使用lru_cache装饰器来缓存count_even_sum函数的结果。def count_even_sum(index, current_sum): 这是一个递归函数,接受两个参数:index表示当前处理到哪个数字组,current_sum表示目前为止所有已选数字的和。
-
递归终止条件:
if index == len(groups): 如果已经处理完所有的数字组,检查current_sum是否为偶数。如果是偶数,则返回 1(表示找到了一种有效的方法),否则返回 0。
-
递归处理:
total_ways = 0: 初始化总的方法计数为 0。- 对于当前组中的每个数字,递归调用
count_even_sum来处理下一个组,并更新current_sum。 total_ways += count_even_sum(index + 1, current_sum + digit): 累加每种选择下的方法数。
-
返回结果:
return count_even_sum(0, 0): 从第一个组开始,初始和为 0,调用递归函数并返回最终结果。
测试样例
-
样例1 (
[123, 456, 789]):- 从每个数字组中选择一个数字,共有 3 * 3 * 3 = 27 种组合方式。其中,有 14 种组合使得各位数字之和为偶数。
-
样例2 (
[123456789]):- 只有一个数字组,所以只需要考虑这个组内的单个数字。其中有 4 个数字(2, 4, 6, 8)是偶数,因此有 4 种方法。
-
样例3 (
[14329, 7568]):- 从每个组中选择一个数字,共有 5 * 4 = 20 种组合方式。其中,有 10 种组合使得各位数字之和为偶数。
通过这种方式,我们可以有效地计算出满足条件的所有可能的选择方法数量。使用 lru_cache 能够显著减少重复计算,提高程序效率。