PAT A1059:Prime Factors

题目描述

1059 Prime Factors (25分)
Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N = p 1 k 1 × p 2 k 2 × … × p m k m N = p_1^{k1}\times p_2^{k2}\times …\times p_m^{k_m} N=p1k1×p2k2××pmkm

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 = p 1 k 1 × p 2 k 2 × … × p m k m N = p_1^{k1}\times p_2^{k2}\times …\times p_m^{k_m} N=p1k1×p2k2××pmkm, where pi’s are prime factors of N in increasing order, and the exponent k i k_i ki is the number of p i p_i pi – hence when there is only one p i p_i pi, k i k_i ki is 1 and must NOT be printed out.

Sample Input:

97532468

Sample Output:

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

求解思路

题意:给出一个int范围的整数,按照从小到大的顺序输出其分解为质因数的乘法算式。
思路:先把素数表打印出来,然后再进行质因子分解的操作。
打印素数表:定义一个数组用以保存100010内的素数。
质因子分解:

  • 定义一个结构体factor用以保存质因子及其个数。考虑到 2 × 3 × 5 × 7 × 11 × 13 × 17 × 19 × 23 × 29 2\times 3\times 5\times 7\times 11\times 13\times 17\times 19\times 23\times 29 2×3×5×7×11×13×17×19×23×29就已经超过了int范围,因此结构体数组长度开到10即可。
  • 对于一个正整数n来说,如果它存在1和本身之外的因子,那么一定是在sqrt(n)的左右成对出现。而这里把这个结论用在“质因子”上面,得到了一个更强化的结论:对一个正整数n来说,如果它存在[2,n]范围内的质因子,那么这些质因子全部小于等于sqrt(n),要么只存在一个大于sqrt(n)的质因子,而其余质因子全部小于等于sqrt(n)。这给质因子分解提供了一个很好的思路:
  • 枚举1~sqrt(n)范围内的所有质因子p,判断p是否是n的因子;
    • 如果p是n的因子,那么给fac数组中增加质因子p,并初始化其个数为0。只要p还是n的因子,就让n不断除以p,每次都让p的个数++,直到p不再是n的因子为止。
    • 如果不是,直接跳过
  • 如果在上面步骤结束后n仍然大于1,说明n有且仅有一个大于sqrt(n)的质因子(有可能是n本身),这是就需要把这个质因子加入fac数组并令其个数为1。
  • 至此,fac数组中存放的就是质因子分解的结果,时间复杂度为 O ( n ) O\left(\sqrt n\right) O(n )

代码实现(AC)

#include<cstdio>
#include<cmath>
const int maxn=100010; 
int Primes[maxn],pNum=0;	//分别用于保存素数,素数的个数 
struct factor{
	int x;		//用于存储质因子 
	int cnt;	//用于存储质因子的个数 
}fac[10];
/*判断是否是质数*/
bool isPrime(int n)
{
	if(n==1)	return false;
	else
	{
		for(int i=2;i<=(int)sqrt(n);i++)
		{
			if(n%i==0)	return false;
		}
		return true;
	}
}
/*打印素数表*/
void find_Primes()
{
	for(int i=1;i<maxn;i++)
	{
		if(isPrime(i))	Primes[pNum++]=i;
	}
}
/*质因子分解操作*/
void solve()
{
	find_Primes();
	int n,num=0;	//n为待分解的数,num为n质因子的个数 
	//printf("%d\n",Primes[0]);
	scanf("%d",&n);
	if(n==1)	printf("1=1");	//1是特殊情况 
	else
	{
		printf("%d=",n);
		/*枚举根号n内的质因子*/ 
		int sqrt_n=(int)sqrt(n);
		for(int i=0;i<pNum&&Primes[i]<=sqrt_n;i++)	
		{
			if(n%Primes[i]==0)	
			{
				/*如果i是n的质因子,则将其添加到fac数组中并让其个数为0*/
				fac[num].x=Primes[i];
				fac[num].cnt=0;
				/*计算质因子Primes[i]的个数*/
				while(n%Primes[i]==0)	
				{
					fac[num].cnt++;
					n/=Primes[i];
				}
				num++;
			}
			if(n==1)	break;	//及时退出循环 
		}
		if(n!=1)
		{
			/*如果无法被根号n内的质因子除尽,那么一定有一个大于根号n的质因子*/	
			fac[num].x=n;
			fac[num].cnt=1;
			num++;
		} 
		/*输出结果*/
		for(int i=0;i<num;i++)
		{
			if(i>0)	printf("*");
			printf("%d",fac[i].x);
			if(fac[i].cnt>1)	printf("^%d",fac[i].cnt); 
		}
	}	
} 
int main()
{
	solve();
	return 0;	
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值