牛客网HJ56 完全数计算

方法一:

思路
要求
输出不超过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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值