版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26398495/article/details/82192117
质因子分解
练习题: PAT. A1059 ||
| 存储结构
- 定义结构体
factor
存放质因子及其个数
//质因数 结构体
struct Factor {
int x; //质因子
int num; //个数
}fac[10]; //int范围内,10位够用了
考虑到 2x3x5x7x11x13x17x19x23x29
就已经超过了int
范围,因此对一个int
范围内的数来说,fac[]
数组的大小只需开到10
就可以了!
| 结论:
- 对于一个正整数
N
,如果它存在[2,N]
的质因子,则要么这些质因子全部小于等于sqrt(N)
,要么只存在一个大于sqrt(N)
的质因子,其余质因子全部小于等于sqrt(N)
;
| 求解思路:获取质因数
- 0、令
remain = N
; - 1、枚举
1 ~ sqrt(N)
范围内所有质因子P
,判断P
是否是N
的质因子:
是:循环相除并记录 ;
否:跳过; - 2、如果以上步骤结束,仍然有
remain > 1
,则说明N
有且仅有一个大于sqrt(N)
的质因子,
加入这个质因子即可!(就是当前剩下的部分remain
)
| 扩展点:
- 如果要求一个正整数
N
的因子个数(注:因子),只需对其质因子分解,得到个质因子的Pi
的个数分别为e1
、e2
、…ek
,于是N
的因子个数就是(e1+1) * (e2+1) * … * (ek+1)
;
【原因:每个质因子Pi
都可以选择出现0
次、1
次、…、ei
次,共ei+1
种可能,组合起来即为上述答案】 - 同理,所有因子之和为:
(1+P1+P1^2+…+P1^e1) * (1+P2+P2^2+…+P2^e2)* … *(1+Pk+Pk^2+…+Pk^ek)
;
| 具体实现:
const int maxn = 100010; //int范围内,素数表开到10^5就够用了!
int prime[maxn], pNum = 0; //素数表, 素数个数
//质因子 结构体
struct Factor {
int x; //质因子
int num; //个数
}fac[10]; //int范围内,10位够用了
//判断素数
bool isPrime( int k) {
if(k <= 1) return false;
int sqt = sqrt(1.0 * k);
for( int i = 2; i <= sqt; i++) {
if(k % i == 0)
return false;
}
return true;
}
//保存素数表
void get_prime(int n) {
for(int i = 2; i < n; i++)
if(isPrime(i)){
prime[pNum++] = i;
}
}
//保存质因子信息
int get_factor(int N) {
int count = 0, remain = N;
int sqt = (int)sqrt(1.0 * N);
for(int i = 0; i < pNum && prime[i] <= sqt; i++) {
if(remain % prime[i] != 0) continue; //不是因子
fac[count].x = prime[i]; //记录该因子
fac[count].num = 0;
while(remain % prime[i] == 0) { //一次性取尽
fac[count].num++; //保存质因子信息
remain /= prime[i];
}
count++; //不同质因子个数+1
if(remain == 1) break; //及时退出循环,节省时间
}
if(remain > 1) { //最后不为1的部分(无法被根号N内的质因子除尽)
fac[count].x = remain;
fac[count++].num = 1;
}
return count;
}
/*质因子分解给定整数,并输出*/
int main() {
int N;
get_prime(maxn);
scanf("%d", &N);
int fac_num = get_factor(N); //质因子分解
//输出
for(int i = 0; i < fac_num - 1; i++) {
if(fac[i].num != 1) printf("%d^%d*", fac[i].x, fac[i].num);
else printf("%d*", fac[i].x);
}
if(fac[fac_num-1].num != 1) printf("%d^%d\n", fac[fac_num-1].x, fac[fac_num-1].num);
else printf("%d\n", fac[fac_num-1].x);
return 0;
}