题目链接
题目描述
问题描述
小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
题目思路
-
遍历每个数字组: 对于每个数字组,分析其中的数字是奇数还是偶数。
-
计算选择方式:
- 记录每个组中奇数和偶数的数量。
- 组合选择时,确保最终数字的和为偶数。
-
动态规划或组合计算: 利用组合数学的原理来计算有效组合的总数。
关键步骤
- 统计每个组中奇数和偶数的数量。
- 根据组合的奇偶性,计算所有可能的组合方式,使得最终数字和为偶数。
复杂度
- 时间复杂度主要取决于数字组的数量和每个组内数字的个数,通常为 O(n * m),其中 n 是数字组的数量,m 是每组的平均数字个数。
存储每种选择的组合数
long long evenCount = 1; // 记录偶数选择的组合数
// 偶数可以什么都不选,所以初始化为1
long long oddCount = 0; // 记录奇数选择的组合数
// 遍历数组中的每个数字
for(auto i:numbers) {
long long even = 0, odd = 0; // 记录当前数字的偶数和奇数的个数
while(i){
int j = i % 10;
i /= 10;
if(j % 2 == 0) even++;
else odd++;
}
// 处理完毕后,我们更新选择的组合数
long long NewevenCount = evenCount * even + oddCount * odd;
long long NewoddCount = oddCount * even + evenCount * odd;
evenCount = NewevenCount;
oddCount = NewoddCount;
}
return evenCount;
我们遍历数组,取出每个数字,算出这个数字的奇数和偶数的数目,然后计算出一共有多少种组合方式
最后输出
题解代码
#include <iostream>
#include <vector>
long long solution(std::vector<int> numbers) {
long long evenCount = 1; // 记录偶数选择的组合数
// 偶数可以什么都不选,所以初始化为1
long long oddCount = 0; // 记录奇数选择的组合数
// 遍历数组中的每个数字
for(auto i:numbers) {
long long even = 0, odd = 0; // 记录当前数字的偶数和奇数的个数
while(i){
int j = i % 10;
i /= 10;
if(j % 2 == 0) even++;
else odd++;
}
// 处理完毕后,我们更新选择的组合数
long long NewevenCount = evenCount * even + oddCount * odd;
long long NewoddCount = oddCount * even + evenCount * odd;
evenCount = NewevenCount;
oddCount = NewoddCount;
}
return evenCount;
}
int main() {
// You can add more test cases here
std::cout << (solution({123, 456, 789}) == 14) << std::endl;
std::cout << (solution({123456789}) == 4) << std::endl;
std::cout << (solution({14329, 7568}) == 10) << std::endl;
return 0;
}
反思
总结要点:
-
功能:
- 函数
solution接受一个整数向量numbers,返回所有可能的组合,使得组合后的数字之和为偶数。
- 函数
-
核心逻辑:
-
初始化两个计数器:
evenCount: 记录当前组合中和为偶数的组合数,初始值为1(表示可以选择零个偶数)。oddCount: 记录当前组合中和为奇数的组合数,初始值为0。
-
遍历每个数字组,统计其中的偶数和奇数的数量。
-
根据当前的偶数和奇数数量,更新组合计数器:
- 新的偶数组合数 = 之前的偶数组合数 * 当前偶数数量 + 之前的奇数组合数 * 当前奇数数量。
- 新的奇数组合数 = 之前的奇数组合数 * 当前偶数数量 + 之前的偶数组合数 * 当前奇数数量。
-
-
返回结果:
- 最后返回
evenCount,即所有组合中和为偶数的组合数。
- 最后返回
-
测试用例:
- 在
main函数中,提供了几个测试用例来验证代码的正确性。
- 在
编译和运行
- 使用 C++ 编译器编译代码并运行测试用例,输出结果表明每个测试用例是否通过。
复杂度
- 时间复杂度是 O(n * m),其中 n 是数字组的数量,m 是每组的平均数字位数,适合处理较小规模的数据。
总体评价
还不错,这个代码竟然还可以输出奇数的选择组合数目,实在是太棒了