方法一:
思路
要求输出不超过n的完全数个数(第40行代码)
把所有可以被n整除的数加起来判断是否与n相同
#include<stdio.h>
int find(int n)
{
int i = 0;
int sum = 0;
for (i = 1; i < n; i++) //除它本身
{
if (n % i == 0) //证明是一个约数
{
sum += i; //把约数相加起来
}
}
if (sum == n) //除自身的约数加起来等于它本身的话
{
return 1;
}
return 0;
}
int main()
{
int n = 0;
int count = 0;
while (scanf("%d", &n) != EOF)
{
int i = 0;
for (i = 1; i <= n; i++)//输出n以内含n完全数的个数
{
int pan = find(i);
if (pan)
{
count++;
}
}
printf("%d\n", count);
}
return 0;
}
方法二:
我们只需要从1开始把所有可以整除n的约数全部加起来即可
约数就是能够被数字整除,而这里简化的一个思路是数字能够被整除,则除数和结果就都是约数,比如:数字 8 , 能够整除 2 ,结果是 4 ,则除数 2 和结果 4 都是约数,而这两个只需要一次计算判断即可。
需要注意的是 4,9,25... 这种,除数和结果相同的情况,则除数或者结果只相加一次就够了,防止重复,这种思路下,只需要从1计算到平方根即可,这里为何可以开平方根呢? sqrt(n)
因为n被1到n-1之间任一整数整除时,两个因子有一个必定小于或等于 根号n
另一个大于或等于根号n
例如16能被2,4,8整除,16=2*8,2小于4,8大于4,因此只需要判定1到根号n有无因子即可
//方法二
/*我们只需要从1开始把所有可以整除n的约数全部加起来即可
约数就是能够被数字整除,而这里简化的一个思路是数字能够被整除,则除数和结果就都是约数,这种思路下,只需
要从1计算到平方根即可,为何是平方根看下面即可
比如:数字 8 , 能够整除 2 ,结果是 4 ,则除数 2 和结果 4 都是约数,而这两个只需要一次计算判断即可。
需要注意的是 4,9,25... 这种,除数和结果相同的情况,则除数或者结果只相加一次就够了
*/
#include<stdio.h>
#include<math.h>
int find(int n)
{
int sum = 1; //因为i从2开始把1跳过了,所以sum等于1加回来
int i = 0;
/* 这里为何可以开平方根呢? sqrt(n)
因为n被1到n-1之间任一整数整除时,两个因子有一个必定小于或等于 根号n
另一个大于或等于根号n
例如16能被2,4,8整除,16=2*8,2小于4,8大于4,因此只需要判定1到根号n有无因子即可*/
for (i = 2; i <= sqrt(n); i++) //这里i没有等于1是因为题目说除了自身以外的约数
{
if (n % i == 0) //是否为约数
{
sum += i;
int m = n / i;
if (i!=sqrt(n)) //例如9=3x3,这是防止重复的数加进来
{
sum += m;
}
}
}
if (sum == n)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int n = 0;
while (scanf("%d", &n) != EOF)
{
int i = 0;
int count = 0; //计数
for (i = 2; i <= n; i++)//对n以内的数字都进行判断是否是完全数,注意1不参与判断
{ //原因是上面sum初始化成1了,如果i等于1的话85行代码sum==n
int pan = find(i); //会多返回一次
if (pan)
{
count++;
}
}
printf("%d\n", count);
}
return 0;
}