完全数是等于其所有真因子(即小于自身的正约数)之和的正整数;例如6的真因子为1、2、3,和为6;1不是完全数(无真因子),枚举时需排除自身、避免重复计数平方根,最直接判断法是遍历1到n−1累加能整除的数并比对。

什么是完全数,以及判断逻辑的边界条件
完全数是指一个正整数等于它所有真因子(即小于它本身的正因数)之和。比如 6 的真因子是 1、2、3,而 1 + 2 + 3 == 6,所以它是完全数。
注意几个关键点:
-
1不是完全数(它没有真因子,和为 0) - 必须严格排除自身,
i == n不能参与求和 - 因子成对出现,但平方根只算一次,比如
sqrt(16) == 4,只加一次 4
用 for 循环暴力枚举真因子并累加
最直接的方式是从 1 枚举到 n - 1,逐个检查是否能整除:
bool isPerfect(int n) {
if (n <p>这种方式简单清晰,但时间复杂度是 <code>O(n)</code>,对大数(如接近 <code>INT_MAX</code>)会明显变慢。实际测试中,<code>isPerfect(33550336)</code> 就会卡住。</p><h3>优化:只遍历到 sqrt(n),避免超时</h3><p>利用因子对称性:若 <code>i</code> 是 <code>n</code> 的因子,那么 <code>n / i</code> 也是。我们只需遍历 <code>i</code> 从 <code>1</code> 到 <code>sqrt(n)</code>:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 若
i * i == n,说明是平方数,i只加一次 - 若
i != 1且i ,则 <code>n / i是另一个真因子,但要确保n / i (即 <code>i > 1自动满足)
bool isPerfect(int n) {
if (n <p>注意:</p>
- 初始化
sum = 1,跳过i = 1的循环处理 i * i 避免浮点误差和 <code>sqrt的类型转换问题- 最后检查
i * i == n时,必须加&& i ,否则 <code>n == 1会误触发
已知完全数极少,可直接查表验证小范围值
目前已知的偶完全数都形如 2^(p−1) × (2^p − 1),其中 2^p − 1 是梅森素数。前五个完全数是:
628496812833550336
对 int 范围内(≤ 2147483647)的输入,只需要比对这 5 个数:
bool isPerfect(int n) {
static const int perfects[] = {6, 28, 496, 8128, 33550336};
for (int p : perfects) {
if (n == p) return true;
if (n <p>这个版本常数时间、零出错风险,适合嵌入性能敏感或输入范围明确的场景。但别忘了:目前尚未发现奇完全数,也未证明其不存在——所以该表只覆盖所有已知偶完全数,且仅限 <code>int</code> 能表示的范围。</p><p>真正容易被忽略的是:<code>n == 1</code> 的边界处理,以及平方根重复累加的条件判断。哪怕只漏掉一个 <code>&& i ,在 <code>n == 4</code> 时就会错误返回 <code>true</code>(因为把 2 加了两次,或误把 4 当作真因子)。</code></p>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










