【问题描述】一个数恰好等于它的因子之和,这个数就称为“完数”。例如,6的因子为1、2、3,并且6=1+2+3,因此6是“完数”。编写程序找出小于给定数n的所有“完数”,n由键盘输入。
【样例输入】1000
【样例输出】6 28 496
【样例说明】28的因子为1、2、4、7、14,并且28=1+2+4+7+14,因此28是“完数”,同理可判断496也是“完数”。判断一个数是否是完数时,因子不包含该数本身。
这个问题目前的思路仅是新手能想出来的:遍历。以下是我第一次写出来的代码
#include<iostream>
using namespace std;
int main()
{
int N;
cin >> N;
for (int i = 3; i < N; i++)
{
int sum = 1;
for (int j = 2; j <= i; j++)
{
if (i % j == 0)
{
sum += j;
}
}
if (sum == i)
{
cout << i << " ";
}
}
cout << endl;
return 0;
}
看起来这串代码没有什么大问题。但是当我调试的时候,发现结果有误:
24并不是一个完数。但是如果细细分析就会发现,24=1+2+3+4+6+8+12+24=60,但是电脑在判断到8的时候sum已经等于24,这个时候它就会直接输出,造成结果错误。那么造成这个结果的原因,自然是因为下面这一段
for (int j = 2; j <= i; j++)
{
if (i % j == 0)
{
sum += j;
if (sum == i)
{
cout << i << " ";
}
}
}
这里使用sum+=j,一定会造成24的结果。那么我们不妨那思路逆转。既然j是i的因子,那么i/j也一定是。那我们改成sum+=i/j试试。并且这里可以自动得到1,我们把sum初始化定义为0。
#include<iostream>
using namespace std;
int main()
{
int N;
cin >> N;
for (int n = 3; n < N; n++)
{
int sum = 0;
for (int i = 2; i <= n; i++)
{
if (n % i == 0)
sum += n / i;
}
if (sum == n)
cout << n << " ";
}
cout << endl;
return 0;
}
可行。问题解决。