题目
一个数如果恰好等于它的所有因子之和,这个数就称为完数。例如,6的因子为1、2、3,而6=1+2+3,因此6是完数。
输入一个正整数n(0<n≤1,000,000,000),请编写程序,找到[0,N]范围之内的所有完数。
输入:
正整数n(0<n ≤1,000,000,000)。
输出:
[0,n]范围之内的所有完数,用逗号分隔。没有则输出None.
示例
输入
30
输出
6,28,
解题思路
完数大家应该不陌生吧,嘿嘿,完数可是C++,python都考得一个小题,今天咱们来看一看完数的两种解题思路,一种是常规解法,一种是算法优化后的解法,大众解法我就不过多的讲了,直接给出小伙伴们代码参考:
代码一(常规版)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
//计算出“完数”
int main(void)
{
int i, j, k, sum;
cout << "请输入所求整数范围上限:" << endl;
cin >> k;//键入范围上限
for (i = 2; i <= k; i++)
{
sum = 0;//保证每一次循环sum都为0
for (j = 1; j < i; j++)
{
if (i % j == 0)//判断j是否为i的因子
sum += j;
}
if (sum == i)//判断因子和与i相等
cout << "完数为:" << i << endl;
}
}
这个代码就不细讲了哈,看代码即可。
接下来,我们讲一下第二种思路,没办法,上面这一种非优化版的在老师发的算法题里面实在是不符合要求,于是自己改进了以下:
代码二(升级版)
int main()
{
int n;
cin>>n;
for (int i = 2; i <= n; i++)
{
int sum = 0;
for (int j = 1; j <= i/2; j++)
{
if (i % j == 0)
{
sum += j;
}
}
if (sum == i)
{
cout<<i<<',';
}
}
}
在这个代码里,我并未添加什么注释,在下面和大家好好唠一唠。
在题中是输入一个数n,求1-n之间的数有几个是完数,毫无疑问,肯定是俩for,你用while啥的也行,主要是能不能把运算的范围缩小一下子,完数,你要遍历一遍,哎!!!等等!!!遍历一遍???遍历半遍行不行,咱试试哈(>-<),拿咱知道的完数6,它的因子是1,2,3,和为6;咱再看看8——1,2,4。。因数和为7,不是完数,再来一个36——1,2,3,4,6,9,12,18。。因数和肯定也不是36,不知道大家有没有发现一个规律,这些数的因子是<=n/2,没错,不管是哪个数,因子中最大的;也就是它本身的一半,也就是说,假如要遍历100这个数,只需要让100分别除以1-50这个区间的数就欧克了,嗯,,在for循环里面那个就可以用j/2就可以了,嘿嘿,试一下这个方法是不是更快,当然,俺们老师发的那个题前7个符合算法,后三个时间超了,这个俺还没想到改进的方法,待以后有思路了再补充 > = <
辛苦大家的小手动一动,给俺点个赞叭 (>+<)