完美数是等于其所有真因子(小于自身的正因数)之和的正整数,如6=1+2+3;c++中可优化至√n时间复杂度:遍历i=1到⌊√n⌋,若i整除n,则累加i及n/i(排除n自身),最后比较和与n是否相等。

什么是完美数,以及C++里怎么快速验证
完美数(Perfect Number)是指一个正整数,它等于其所有**真因子**(即小于它本身的正因数)之和。比如 6 的真因子是 1、2、3,而 1 + 2 + 3 = 6,所以 6 是完美数。
在 C++ 中判断一个数 n 是否为完美数,核心就是:枚举所有真因子并求和,再比对是否等于 n。但暴力从 1 枚举到 n-1 效率太低(尤其对大数),实际应只遍历到 sqrt(n)。
用 sqrt 优化因子枚举,避免超时或溢出
枚举因子时,若 i 能整除 n,则 n/i 也是因子。但要注意三点:
- 只考虑
i 和 <code>n/i ,因为真因子必须严格小于 <code>n; -
i == 1时,n/i就是n本身,要跳过; - 当
i * i == n(即n是完全平方数),i只能加一次,否则重复计入。
示例代码片段(处理正整数 n):
if (n 1 时) for (int i = 2; i * i <h3>注意边界情况和数据类型陷阱</h3><p>常见出错点不是逻辑,而是边界和类型:</p>
n 直接返回 <code>false——1 没有真因子,0 和负数不属定义域;- 用
int存sum可能溢出(如测试n = 8128,真因子和也是 8128,没问题;但若误算进n自身,就变成 16256,可能溢出);稳妥起见用long long; i * i 中,若 <code>i很大,i * i可能溢出int——改用i 或更安全的 <code>i (整数除法);- LeetCode 上的题(如 #507)明确限定输入是
int范围内的正整数,但已知的偶完美数都形如2^(p−1)(2^p − 1),其中2^p − 1是梅森素数;实际中n > 1e8基本不会是完美数,可加早退判断。
为什么不用预计算打表?
目前已知的偶完美数极少(截至 2024 年共 51 个),且都极大(最大已知超过千万位);奇完美数是否存在仍是未解数学问题。因此:
- 对一般编程题(如输入
int范围内),真正符合条件的只有 6、28、496、8128、33550336 这 5 个; - 有人直接写
return n == 6 || n == 28 || n == 496 || n == 8128 || n == 33550336;,确实快,但丧失通用性; - 面试或工程中若强调鲁棒性和可维护性,仍建议用带优化的因子求和法——它逻辑清晰、易于验证、不依赖外部知识。
最易被忽略的是 n == 1 和 i == n/i 时的去重处理,这两个地方写错,6 和 28 就会判错。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











