复试算法练习Day14——完全数计算

复试算法练习Day14——完全数计算

题目描述

完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。

它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。

例如:28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。

输入n,请输出n以内(含n)完全数的个数。

数据范围: 1 \le n \le 5 \times 10^{5} \1≤n≤5×105

输入描述:

输入一个数字n

输出描述:

输出不超过n的完全数的个数

示例1

输入:

1000

复制

输出:

3

思路

思路一:通过完全数的要求根据定义如果一个数恰好等于它的因子之和,则称该数为"完全数",则按要求将一个数的因子加和与其本身对比,如果相同则正确,不同则失败

思路二:通过梅森素数来确定最终结果是不是完全数,如果(2p-1)是素数,那么它就是梅森素数,再根据用(2p-1)*2^(p-1),这个就是完全数

具体实现

//写C语言情况下的运算
//根据定义计算
//如果一个数恰好等于它的因子之和,则称该数为"完全数"
#include<iostream>
#include<time.h>
//计算出Rmax以内的所有完全数
#define Rmax 100000
//名字空间初始化
using namespace std;
 
void main() {
	
 //求解其完全数的因子
	for (int i = 3; i <= Rmax; ++i) {
		//计算所有因子的和
        int sum = 1;
		for (int j = 2; j < i; ++j) {
			if (i%j == 0) {
                //说明j是i的因子
                //并对因子求和
				sum += j;
			}
		}
		//判断和是否等于数本身
		if(sum==i){
			cout << i << endl;
		}
	}
	system("pause");
}
//方案二:通过梅森素数来确定最终结果是不是完全数
//如果(2^p-1)是素数,那么它就是梅森素数,
//再根据用(2^p-1)*2^(p-1),这个就是完全数
#include<iostream>
#include<time.h>
#include<math.h>
//定义一个极大的数
#define max 1000000000 
using namespace std;
//素数初始化
bool Prime(int prime);
 
void main() {
	//设置时钟来显示运算速度,来表示时间复杂度
    clock_t start, end;
	start = clock();
   //判断一个数是否为梅森素数
    //如果是则将其因子求和
	for (int p = 2;; ++p) {
		int perfect = (pow(2,p) - 1) * pow(2 ,p - 1);
		if (perfect > max)break;
		int prime = pow(2, p) - 1;
		if (Prime(prime))cout << perfect << endl;
	}
    //求解梅森素数算法所需时间输出
	end = clock();
	float time = (float)(end - start) / 1000;
	cout << "time is" << time << "s" << endl;
	system("pause");
}
//求解是否为质数 
bool Prime(int prime) {
	//假设选择的数为质数
    bool choice = true;
	int k = sqrt((float)prime);
 	//判断因子之和和本身是否相同
	for (int j = 2; j <= k; ++j) {
		//如果不是质数,则输出错误返回
        if (prime % j == 0) {
			choice = false;
			break;
		}
	} 
	return choice;
}

时间复杂度

对于方案一,在遍历的时候采用了两次for循环首先遍历出因子,然后将因子加和,所以时间复杂度为O(n^2),空间复杂度也为O(n)

对于方案二,采用先判断是否为梅森素数,之后采用素数来判断是否为完全数,只遍历了一次,所以时间复杂度为O(n),空间复杂度也为O(n)

小结

在C语言中采用判断是否为完全数的时候,可以先对需要运算的算法计时,通过计时来判断运算的速度,从而确定算法的速度快慢,然后根据题目要求,可以采用直接加和因子的方法用定义求解完全数,也可以利用梅森素数的求解,先求解梅森素数,然后利用梅森素数求完全数的算法来计算最终结果,采用不同的原理可以使算法的时间复杂度降低,加快算法输出速度,也是可以让我们看到更多的方法来针对具体问题,通过不同角度具体分析,具有良好的借鉴意义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值