PAT Advanced1059 Prime Factors(建立素数表)

本文详细介绍了如何使用埃氏筛选法(Eratosthenes筛选法)建立素数表,并利用此表进行质因数分解的过程。通过具体示例,展示了如何将一个正整数分解为其质因数的乘积形式,包括算法实现的代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:PAT Advanced1059

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N = p1k₁​​ × p2k₂​ × ⋯ × p​m km​​​ .

Input Specification:

Each input file contains one test case which gives a positive integer N in the range of long int.

Output Specification:

Factor N in the format N = p1​​ ^ k​1 * p2​​ ^ k​2​​ * … * p​m​​ ^ k​m​​ , where p​i​​ 's are prime factors of N in increasing order, and the exponent k​i​​ is the number of pi​​ – hence when there is only one pi​ , k​i​​ is 1 and must NOT be printed out.

Sample Input:

97532468

Sample Output:

97532468 = 2 ^ 2 * 11 *17 * 101 * 1291



要求就是质因子(素数因子)分解:将一个正整数n写成一个或多个质数的乘积的形式。

对于一个正整数n来说,如果它存在1和本身以外的因子,那么一定是在sqrt(n)的左右成对出现。

所以,只需要建立 [2 , sqrt(n)] 范围内的素数表,然后遍历素数表找出n的因子及个数。


建立素数表:
逐个判断: 遍历 [2 , sqrt(n)] ,判断每一个是否为素数。时间复杂度为O(n√n)

埃氏筛选法(Eratosthenes 筛选法):从第一个素数 “2” 的开始,筛选掉 2~maxn 的所有 “2” 的倍数,继续遍历,若遍历到的数已被筛选掉,则跳过;反之该数为素数,进行同 “2” 的操作。
时间复杂度为O(nloglogn)

ps.可以利用map、set容器在内部自动从小到大排序的特性。



以下代码:

#include<iostream>
#include<set>
#include<cmath>
#include<map>
using namespace std;
set<int> prime;            //用于存储素数表
map<int,int> ans;
void find_prime(int maxn)  //建立素数表
{
	set<int> temp;         //用于存储已被筛选掉的元素
	for(int i=2;i<=maxn;i++)
	{
		if(!temp.count(i))             //若未被筛选掉
		{
			prime.insert(i);           //则是素数
			for(int j=i;j<=maxn;j+=i)  //并筛选掉其所有倍数
				temp.insert(j);
		}
	}
}
int main()
{  
	int temp,n;
	cin>>n;
	temp=n;
	find_prime(sqrt(n));
	set<int>::iterator it1;
	for(it1=prime.begin();it1!=prime.end();it1++)
	{
		int t=*it1;
		while(n%t==0)
		{
			if(!ans.count(t))
				ans[t]=1;
			else
				ans[t]++;
			n/=t;
		}
	}
	cout<<temp<<"=";
	if(ans.empty())   //不要漏了这个
		cout<<temp;
	else
	{
		map<int,int>::iterator it2;
		for(it2=ans.begin();it2!=ans.end();it2++)
		{
			if(it2!=ans.begin())
				cout<<"*";
			cout<<(*it2).first;
			if((*it2).second!=1)
				cout<<"^"<<(*it2).second;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值