(PAT Advanced)1059 Prime Factors (整数的素因子分解) C++

原题:https://pintia.cn/problem-sets/994805342720868352/problems/994805415005503488
在这里插入图片描述
题目大意
将一个大整数分解成多个质数的乘积,具体请搜索数论——正整数的唯一分解定理。

解法1(素数筛选和匹配)

筛选法的思路是建议一个大小为maxn的素数表,假定初始全是素数,然后逐个划掉,即1不是素数,花掉;2是素数,则所有2的倍数均不是素数,花掉;依此类推。还应该注意,整数的一对素因子不可能同时大于sqrt(x),即若ln的最大素因子,sn的另一个素因子,则n=l*s≥s*s,所以整数一定存在素因数小于其算术平方根。
则有如下素数筛选解法:

#include<vector>
#include<iostream>

using namespace std;

typedef long int ll;
const int maxn = 1e4; 
vector<int> prime(maxn, 0);  // 0表示是素数,1表示不是素数

int main() {
	// 建立一个素数表
	int i, j;
	for (i = 2; i*i < maxn; i++) {
		if (prime[i] == 1) continue; // 已经筛选过了
		for (j = 2; i*j < maxn; j++)
			prime[i*j] = 1; // 剔除掉
	}
	ll num;
	cin >> num;
	printf("%ld=", num);
	if (num == 1) printf("1\n");
	bool state = false; // 表明是否已经输出过元素了
	for (i = 2; num >= 2; i++) {
		int cnt = 0;// 指数
		int flag = 0; // i是否是因子
		while (prime[i] == 0 && num % i == 0) {
			cnt++; flag = 1;
			num /= i;
		}
		if (flag) { // 是因子
			if (state) printf("*");
			printf("%d", i);
			state = true;
		}
		if (cnt >= 2) printf("^%d", cnt);
	}
	system("pause");
	return 0;
}

解法2(素数搜索)

基于以下几个特点:

  • 整数x存在素因子小于sqrt(x)
  • 若找到一个素因子a,则可以在 x/a下继续寻找

我们有如下找素因子的解法:

for (ll i = 2; i * i <= num; i++) {
		while (num % i == 0) { //能够整除
			factor[i]++;
			num /= i;
		}
	}

总的解法:

/* 1059 Prime Factors (25 分) */
// 素数因子 整数的质因数分解
/* 1. 整数的素数因子因小于sqrt(x)
*  2. 若找到整数一个素数因子 a, 则在x/a后再继续找
*/
#include<map>
#include<iostream>

using namespace std;

typedef long int ll;

int main() {
	ll num;
	map<ll, int> factor;
	cin >> num;
	printf("%ld=", num);
	if (num == 1) printf("1\n");
	for (ll i = 2; i * i <= num; i++) {
		while (num % i == 0) { //能够整除
			factor[i]++;
			num /= i;
		}
	}
	if (num != 1) factor[num]++;
	for (auto iter = factor.begin(); iter != factor.end(); iter++) {
		if (iter != factor.begin()) printf("*");
		int p = iter->first, k = iter->second;
		printf("%ld", p);
		if (k != 1) printf("^%d", k);
	}
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值