合数分解(质因数分解)
简介
将该合数分解成质因数,统计出出现不同的质因数的个数,分别出现过的质因数为哪几个,以及出现过的质因数的数量。
方法
使用欧拉筛对合数范围内的质数进行筛选,之后对该合数进行质因数的分解
代码
#include<iostream> #include<cstdio> using namespace std; int prime[10001]; bool p[10001]; int cnt = 0; int factor[10001][2]; int fatcnt = 0; void findfactors(int x) { for (int i = 2; i <= x; i++) { if (!p[i])prime[cnt++] = i; for (int j = 0; j<cnt; j++) { if (prime[j] * i > x)break; p[prime[j] * i] = true; if (i%prime[j] == 0)break; } } } int getFactors(int x) { int tmp = x; for (int i = 0; prime[i] <=tmp / prime[i]; i++)//prime[i] <= tmp / prime[i]只需要计算到“中间的”位置,剩下的在while循环中tmp /= prime[i];会出现 { if (tmp%prime[i] == 0) { factor[fatcnt][0] = prime[i];//记录这个质数 while (tmp%prime[i] == 0)//使用while循环来记录这个质数在合数的因子中出现的次数 { factor[fatcnt][1]++; tmp /= prime[i]; } } fatcnt++; } if (tmp != 1) { factor[fatcnt][0] =tmp; factor[fatcnt++][1] = 1;//注意这里也要加一 } return fatcnt; }
例题
https://www.luogu.com.cn/problem/P2043
分析
其实不用求解n!,而且10000!大的没边了,因为阶乘也是从1乘到n的,所以我们可以从2循环到n,每个数字都进行质因数的分解,最后汇总即可
代码
#include<iostream> #include<cstdio> using namespace std; int prime[10001]; bool p[10001]; int cnt = 0; int factor[10001][2]; int fatcnt = 0; void findfactors(int x) { for (int i = 2; i <= x; i++) { if (!p[i])prime[cnt++] = i; for (int j = 0; j<cnt; j++) { if (prime[j] * i > x)break; p[prime[j] * i] = true; if (i%prime[j] == 0)break; } } } void getFactors(int x) { int tmp = x; for (int i = 0; prime[i] <= tmp / prime[i]; i++)//prime[i] < tmp / prime[i]只需要计算到“中间的”位置,剩下的在while循环中tmp /= prime[i];会出现 { if (tmp%prime[i] == 0) { factor[prime[i]][0] = prime[i];//记录这个质数 while (tmp%prime[i] == 0)//使用while循环来记录这个质数在合数的因子中出现的次数 { factor[prime[i]][1]++; tmp /= prime[i]; } } } if (tmp != 1) { factor[tmp][0] = tmp; factor[tmp][1] ++;//注意这里也要加一 } } int main() { int n; std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); cin >> n; findfactors(10000); for (int i = 2; i <= n; i++) getFactors(i); for (int i = 0; i <=n; i++) if(factor[i][1]!=0) printf("%d %d\n", factor[i][0], factor[i][1]); }