史密斯数是合数,其各位数字之和等于其质因数分解中所有质因数(含重复)的各位数字之和;例如27=3×3×3,2+7=3+3+3=9,故27是史密斯数;质数和1均不符合定义。

什么是史密斯数?先看判定逻辑
一个合数 n 是史密斯数,当且仅当它各位数字之和等于其所有质因数(含重复)的各位数字之和。注意:质数不算史密斯数,1 也不是——必须是合数。
比如 27:各位和是 2 + 7 = 9;质因数分解为 3 × 3 × 3,质因数数字和是 3 + 3 + 3 = 9,所以是史密斯数。而 13 是质数,直接排除。
怎么写 digitSum() 才不漏掉前导零或负数?
这个辅助函数要稳健处理任意整数输入,尤其避免把 0 当空、或对负数取模出错。
- 用
abs(n)统一转正,再逐位取模:n % 10,然后n /= 10 - 特别处理
n == 0的情况——直接返回0,否则循环进不去 - 别用字符串转换(如
to_string),在嵌入式或竞赛环境下可能带来隐式开销
示例:digitSum(100) 必须返回 1,不是 100 字符串长度。
质因数分解时,i 循环到 sqrt(n) 还是 n?
必须只循环到 sqrt(n),否则超时(比如判断 10^9 级别的数)。但要注意残留的大于 sqrt(n) 的质因数。
- 从
i = 2开始试除,每次除尽就累加digitSum(i) - 循环结束后若
n > 1,说明剩下一个质因数(就是当前的n),再加一次digitSum(n) - 别忘了跳过质数判断——史密斯数要求合数,所以如果原数
n最终只剩自己且没被除过(即未进入循环),说明它是质数,直接返回false
常见错误:漏掉最后那个大质因数,导致质因数数字和偏小,误判成史密斯数。
isSmith(int n) 函数里最容易忽略的边界条件
很多实现能跑通样例但在线评测 WA,往往栽在这些地方:
n 或 <code>n是质数 → 直接返回false,不能只靠质因数和相等就放行- 质因数分解过程中,重复质因数要全部计入(比如
8 = 2×2×2,得加三次digitSum(2)) - 用
int存n没问题,但中间计算如digitSum不会溢出;不过若扩展到大数,需改用long long并调整sqrt类型
真正麻烦的是“合数但质因数和恰好等于各位和”的稀疏性——测试时别只用 4、22、27,至少补一个 58(5+8=13,2+2+9=13)验证重复质因数逻辑。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











