数字阶乘和问题调试及现代C++ STL优化实现问询
C++求解阶乘数位和系列问题优化方案
原代码核心问题
- 逻辑偏差:题目中
f(n)是n的各位数字的阶乘之和,而非n本身的阶乘,原代码核心计算逻辑完全不符合题目定义 - 效率极低:暴力枚举所有可能的n,没有利用0-9阶乘固定的特性,存在大量重复计算
- 冗余操作:频繁创建vector计算数位和,带来不必要的内存开销和性能损耗
优化思路
核心目标:找到满足
sf(n)=i的最小正整数n,优先保证数位最少,其次保证数值最小
- 预存常量:0-9的阶乘是固定值,直接预存在数组中,避免重复计算
- BFS遍历:按数位长度从小到大枚举所有可能的n,第一个匹配到对应i的n就是最小的g(i),天然满足最小要求
- 状态传递:BFS队列同时保存当前数值和当前的f(n)值,不需要每次重新计算各位阶乘和
- 轻量计算:数位和计算直接操作整数,不需要额外创建vector
- 结果缓存:用数组记录1-150范围内每个i对应的g(i),找到后直接跳过后续匹配,避免重复计算
优化代码实现
#include <iostream> #include <queue> #include <array> #include <vector> using namespace std; // 预存0-9的阶乘 const array<int, 10> fact = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; // 计算整数的数位和 inline int digit_sum(int x) { int sum = 0; while (x > 0) { sum += x % 10; x /= 10; } return sum; } int main() { const int MAX_I = 150; vector<long long> g(MAX_I + 1, 0); // 存每个i对应的最小n,用long long避免溢出 queue<pair<long long, int>> q; // 队列元素:<当前数值n, 当前f(n)的值> // 初始化队列,放入1-9的个位数 for (int d = 1; d <= 9; d++) { long long n = d; int fn = fact[d]; int sfn = digit_sum(fn); if (sfn <= MAX_I && g[sfn] == 0) { g[sfn] = n; } q.emplace(n, fn); } // BFS扩展 int found = 0; for (int i = 1; i <= MAX_I; i++) if (g[i] != 0) found++; while (found < MAX_I && !q.empty()) { auto [cur_n, cur_fn] = q.front(); q.pop(); // 追加0-9生成新数 for (int d = 0; d <=9; d++) { long long new_n = cur_n * 10 + d; int new_fn = cur_fn + fact[d]; int sfn = digit_sum(new_fn); if (sfn <= MAX_I && g[sfn] == 0) { g[sfn] = new_n; found++; if (found == MAX_I) break; // 全部找到直接退出 } q.emplace(new_n, new_fn); } if (found == MAX_I) break; } // 计算sg(i)的和 long long total = 0; for (int i =1; i <= MAX_I; i++) { total += digit_sum(g[i]); } cout << "1<=i<=150的∑sg(i)值为:" << total << endl; return 0; }
该方案利用现代C++特性和BFS的特性,全程无冗余计算,几毫秒即可得到最终结果,完全解决了原代码耗时长的问题。
内容的提问来源于stack exchange,提问作者Abdelhamid CHEIKH
相关产品推荐
相关产品推荐

