《算法笔记》5.5小节——数学问题->质因子分解

目录

问题 A: 完数

问题 B: 完数

问题 C: 质因数的个数

问题 D: 约数的个数

问题 E: 完数与盈数


问题 A: 完数

题目描述

    求1-n内的完数,所谓的完数是这样的数,它的所有因子相加等于它自身,比如6有3个因子1,2,3,1+2+3=6,那么6是完数。即完数是等于其所有因子相加和的数。

输入

    测试数据有多组,输入n,n数据范围不大。

输出

    对于每组输入,请输出1-n内所有的完数。如有案例输出有多个数字,用空格隔开,输出最后不要有多余的空格。

样例输入

6

样例输出

6

题解

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int main(){
	int n;
	while(scanf("%d", &n) != EOF){
		int sum, flag = 0;
		int i, j;
		for(i = 1; i <= n; i++){
			sum = 0;
			for(j = 1; j <= i / 2; j++){
				if(i % j == 0){
					sum = sum + j;
				}	
			}
			if(sum == i){//完数
				if(flag == 0){
					printf("%d", i);
					flag = 1;
				}
				else{
					printf(" %d", i);
				}
			}
		}
		if(flag){
			printf("\n");
		}
	}
    return 0;
}

问题 B: 完数

题目描述

    求1-n内的完数,所谓的完数是这样的数,它的所有因子相加等于它自身,比如6有3个因子1,2,3,1+2+3=6,那么6是完数。即完数是等于其所有因子相加和的数。

输入

    测试数据有多组,输入n,n数据范围不大。

输出

    对于每组输入,请输出1-n内所有的完数。如有案例输出有多个数字,用空格隔开,输出最后不要有多余的空格。

样例输入

6

样例输出

6

题解

 

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int main(){
	int n;
	while(scanf("%d", &n) != EOF){
		int sum, flag = 0;
		int i, j;
		for(i = 1; i <= n; i++){
			sum = 0;
			for(j = 1; j <= i / 2; j++){
				if(i % j == 0){
					sum = sum + j;
				}	
			}
			if(sum == i){//完数
				if(flag == 0){
					printf("%d", i);
					flag = 1;
				}
				else{
					printf(" %d", i);
				}
			}
		}
		if(flag){
			printf("\n");
		}
	}
    return 0;
}

问题 C: 质因数的个数

题目描述

求正整数N(N>1)的质因数的个数。
相同的质因数需要重复计算。如120=2*2*2*3*5,共有5个质因数。

输入

可能有多组测试数据,每组测试数据的输入是一个正整数N,(1<N<10^9)。

输出

对于每组数据,输出N的质因数的个数。

样例输入

120
200

样例输出

5
5

提示

注意1不是N的质因数;若N为质数,NN的质因数。

题解

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 100010;
int prime[maxn], pNum = 0;
bool is_prime(int n){//判断n是否为素数 
	if(n == 1){
		return false;
	}
	int sqr = (int)sqrt(1.0 * n);
	int i;
	for(i = 2; i <= sqr; i++){
		if(n % i == 0){
			return false;
		}
	}
	return true;
}
void Find_Prime(){//素数表 
	int i;
	for(i = 1; i < maxn; i++){
		if(is_prime(i) == true){
			prime[pNum++] = i;
		}
	}
}
int main(){
	Find_Prime();
	int n;
	while(scanf("%d", &n) != EOF){
		int num = 0, ans = 0;
		int i;
		int sqr = (int)sqrt(1.0 * n);
		for(i = 0; i < pNum && prime[i] <= sqr; i++){
			while(n % prime[i] == 0){
				ans++;
				n = n / prime[i];
			}
		}
		if(n != 1){
			ans++;
		}
		printf("%d\n", ans);
	}
    return 0;
}

问题 D: 约数的个数

题目描述

输入n个整数,依次输出每个数的约数的个数。

输入

输入的第一行为N,即数组的个数(N<=1000)
接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
当N=0时输入结束。

输出

可能有多组输入数据,对于每组输入数据,
输出N行,其中每一行对应上面的一个数的约数的个数。

样例输入

6
1 4 6 8 10 12
0

样例输出

1
3
4
4
4
6

题解

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 100010;
int prime[maxn], pNum = 0;
bool is_prime(int n){//判断n是否为素数 
	if(n == 1){
		return false;
	}
	int sqr = (int)sqrt(1.0 * n);
	int i;
	for(i = 2; i <= sqr; i++){
		if(n % i == 0){
			return false;
		}
	}
	return true;
}
void Find_Prime(){//素数表 
	int i;
	for(i = 1; i < maxn; i++){
		if(is_prime(i) == true){
			prime[pNum++] = i;
		}
	}
}
struct factor{
	int x;
	int cnt;
}fac[10];
int main(){
	Find_Prime();
	int N;
	while(scanf("%d", &N) != EOF){
		if(N == 0){
			break;
		}
		while(N--){
			int n;
			scanf("%d", &n);
			int num = 0;
			int i;
			int sqr = (int)sqrt(1.0 * n);
			for(i = 0; i < pNum && prime[i] <= sqr; i++){
				if(n % prime[i] == 0){//prime[i]是n的因子 
					fac[num].x = prime[i];
					fac[num].cnt = 0;
					while(n % prime[i] == 0){//计算prime[i]的个数 
						fac[num].cnt++;
						n = n / prime[i];
					}
					num++;
				}
				if(n == 1){
					break;
				} 
			}
			if(n != 1){//有一个大于根号n的质因子 
				fac[num].x = n;
				fac[num++].cnt = 1;
			}
			int count = 1;
			for(i = 0; i < num; i++){
				count = count * (fac[i].cnt + 1);
			}
			printf("%d\n", count);
		}
	}
    return 0;
}

问题 E: 完数与盈数

题目描述

一个数如果恰好等于它的各因子(该数本身除外)子和,如:6=3+2+1,则称其为“完数”;

若因子之和大于该数,则称其为“盈数”。求出2 到60 之间所有“完数”和“盈数”,并以如

下形式输出: E: e1 e2 e3 ......(ei 为完数) G: g1 g2 g3 ......(gi 为盈数)

输入

输出

按描述要求输出(注意EG后面的冒号之后有一个空格)。

题解

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int main(){
	int wan[60], ying[60], m = 0, n = 0;
	int i, j;
	for(i = 2; i <= 60; i++){
		int sum = 0;
		for(j = 1; j < i; j++){
			if(i % j == 0){
				sum = sum + j;
			}	
		}	
		if(sum == i){//完数 
			wan[m++] = i;
		}
		else if(sum>i){//盈数 
			ying[n++] = i;
		}
	}
	printf("E: ");
	for(i = 0; i < m; i++){
		printf("%d ", wan[i]);
	}
	printf("G: ");
	for(i = 0; i < n; i++){
		printf("%d", ying[i]);
		if(i != n - 1){
			printf(" ");
		}	
		else{
			printf("\n");
		}	
	}
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值