【知识点5】质因子分解

1. 质因子分解

质因子分解是指将一个正整数n写成一个或者多个质数的乘积的形式

注意:由于1本身并不是素数,因此它没有质因子。 但是对于有些正整数n的题目需要特判1,比如【PAT A1059】Prime Factors这道题就需要特判。

由于每个质因子都可以不止出现一次,因此不妨定义结构体factor(因子),用来存放质因子及其个数,如下所示:

struct factor{
	int x;		//x是质因子 
	int cnt;	//cnt是质因子的数量 
}fac[10];

这里的fac[]数组存放的就是给定的正整数n的所有质因子。例如,对于180来说,fac数组如下:
在这里插入图片描述
考虑到 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范围,因此对一个int型范围的数来说,fac数组的大小只需要开到10就可以了。

前面提到过,对一个正整数n来说,如果它存在1和本身之外的因子,那么一定是在sqrt(n)的左右成对出现的。而这里把这个结论用在“质因子”上面,会得到一个强化的结论:

  • 对一个正整数n来说,如果它存在[2,n]范围内的质因子,要么这些质因子全部 小于等于 sqrt(n),要么只存在 一个大于 sqrt(n)的质因子,而其余质因子全部 小于等于 sqrt(n)

上述的结论为质因子分解提供了一个很好的思路 (三步走)

  1. 打印[1,sqrt(n)]范围内的素数表

  2. 枚举1 ~ sqrt(n)范围内的所有质数,判断p是否是n的因子。

    • 如果pn的因子,那么fac数组中添加质因子p,并初始化其个数为0.然后,只要p还是n的因子,就让n不断除以p,每次操作令p的个数加1,直到p不再是n的因子为止。
    • 如果p不是n的因子,就直接跳过。
    if(n % prime[i] == 0){
    	fac[num].x = prime[i];
    	fac[num].cnt = 0;
    	while(n % prime[i] == 0){
    		fac[num].cnt++;
    		n /= prime[i];
    	}
    	num++;
    } 
    
  3. 如果在上面步骤结束之后,n仍然是大于1,说明n有且仅有一个大于sqrt(n)的质因子(有可能是n本身),这时需要把这个质因子加入fac数组,并令其个数为1.

    if(n != 1){
    	fac[num].x = n;
    	fac[num++].cnt = 1;
    }
    

至此,fac数组中存放的就是质因子分解的结果,时间复杂度为 O ( n ) O(\sqrt n) O(n )

2. 如何求所有因子个数,以及所有因子之和

在这里插入图片描述

  • 上面的性质需要特别理解!
  • 等比公式!
  • 因为是质因子,所以它们之间肯定是不相等的,所以一定能保证有那么多的因子数。

3. 题型训练

  1. 【PAT A1059】Prime Factors
  2. 【PAT A1096】Consecutive Factors

4. 参考文档

  1. 算法笔记
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值