青训营刷题笔记:数字分组与选择问题 | 豆包MarsCode AI刷题

146 阅读5分钟

青训营刷题笔记:数字分组与选择问题

问题描述

小M面对一个包含多组数字的列表,需要从每组中选择一个数字组成一个新数,并要求这个新数的各位数字之和为偶数。任务是计算出满足条件的选择方法总数。

分析思路

要满足数字之和为偶数,需统计每组中奇数和偶数的数量,并通过组合推算满足条件的方案总数。

  1. 初始化状态
    假设开始时没有选任何数字,视为一个"空组合"。空组合的数字和为 0(偶数),因此初始 even_count = 1odd_count = 0

  2. 遍历每组数字
    对于每一组数字,统计其中奇数 (current_odd) 和偶数 (current_even) 的数量。

  3. 更新组合状态
    当前选择对整体偶奇状态的影响如下:

    • 新的偶数组合数:
      由之前的偶数组合数搭配当前偶数,或奇数组合数搭配当前奇数得到。
    • 新的奇数组合数:
      由之前的偶数组合数搭配当前奇数,或奇数组合数搭配当前偶数得到。 公式如下:
    new_even_count = even_count * current_even + odd_count * current_odd
    new_odd_count = even_count * current_odd + odd_count * current_even
    
  4. 最终结果
    所有组合中,满足条件的方案数即为最终 even_count


代码实现

def solution(numbers):
    # 初始化偶数和奇数的组合数
    even_count, odd_count = 1, 0  # 初始状态:一个空集,和为偶数

    # 遍历每个数字组
    for group in numbers:
        current_even, current_odd = 0, 0

        # 统计该数字组中奇数和偶数的数量
        for digit in str(group):
            if int(digit) % 2 == 0:
                current_even += 1
            else:
                current_odd += 1

        # 更新组合的状态
        new_even_count = even_count * current_even + odd_count * current_odd
        new_odd_count = even_count * current_odd + odd_count * current_even

        even_count, odd_count = new_even_count, new_odd_count

    # 返回最后的偶数组合数
    return even_count

# 测试样例
if __name__ == "__main__":
    print(solution([123, 456, 789]) == 14)  # 输出 True
    print(solution([123456789]) == 4)       # 输出 True
    print(solution([14329, 7568]) == 10)    # 输出 True

测试样例

  1. 样例1
    输入:numbers = [123, 456, 789]
    分析:

    • 第一组:奇数 1, 3,偶数 2 → 奇数 2 个,偶数 1 个。
    • 第二组:奇数 5,偶数 4, 6 → 奇数 1 个,偶数 2 个。
    • 第三组:奇数 7, 9,偶数 8 → 奇数 2 个,偶数 1 个。
      输出:14
  2. 样例2
    输入:numbers = [123456789]
    分析:奇数 5 个,偶数 4 个。
    输出:4

  3. 样例3
    输入:numbers = [14329, 7568]
    分析:

    • 第一组:奇数 3 个,偶数 2 个。
    • 第二组:奇数 3 个,偶数 1 个。
      输出:10

总结

本题利用动态规划的思想,通过记录奇偶组合状态的转移,避免暴力穷举所有组合,降低了计算复杂度。核心难点在于推导偶奇状态转移公式,解决过程也体现了数学分析与编程实现的结合。数字分组与选择问题总结

本题的目标是从多个数字组中选择数字组成一个新数,使其各位数字之和为偶数,并计算符合条件的组合方式数量。核心考点是奇偶性质对数字和的影响,以及如何通过动态规划思想高效计算结果。

解题思路

  1. 奇偶性质分析
    一个数的各位数字之和为偶数,当且仅当选择的数字中奇数的个数为偶数。因此,问题可以转化为统计选择数字后奇数总个数为偶数的方案数。

  2. 动态规划状态转移
    使用两个变量 even_countodd_count 分别记录当前组合中奇数和偶数的方案数。

    • 初始状态:组合为空,和为偶数,even_count = 1odd_count = 0

    • 遍历每个数字组时,统计其中的奇偶数字数量:

      • 新的偶数组合数 = 之前偶数组合数 × 当前偶数数量 + 之前奇数组合数 × 当前奇数数量。
      • 新的奇数组合数 = 之前偶数组合数 × 当前奇数数量 + 之前奇数组合数 × 当前偶数数量。
    • 更新后,继续处理下一个数字组。

  3. 边界处理
    当所有数字组遍历完成后,结果即为 even_count 的值,表示满足条件的方案总数。

实现效果

通过动态规划避免了对所有可能组合的暴力穷举,大大降低了复杂度。以 numbers = [123, 456, 789] 为例:

  • 第一组奇偶分布为奇数 2、偶数 1,更新后偶数组合数为 1。
  • 第二组奇偶分布为奇数 1、偶数 2,更新后偶数组合数为 6。
  • 第三组奇偶分布为奇数 2、偶数 1,更新后偶数组合数为 14。
    最终输出结果为 14

总结

本题通过奇偶性质的分析,将问题抽象为动态规划的状态转移,避免了组合的暴力穷举。核心难点在于公式推导以及状态的正确更新。这种方法不仅提升了效率,还增强了对数学与编程结合问题的解决能力,适合处理类似组合与选择类的题目。