1.问题描述:
题目意思是给定一个整型范围内的n求出这个n能够分解的质因数,若某一个质因子的分解个数超过一个那么使用^次方表示,比如4 = 2 * 2就要写成4 = 2 ^ 2.这样的形式。
2.算法分析:
其实这一道题目是一道纯数学知识题,首先我们要理解质因子,质数就是素数,我们需要先用线性筛筛出一定范围的素数,打个表。这里给出埃式筛法,时间复杂度为O(nlogn)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 1e7 + 5;
bool prime[maxn];
int main() {
for (LL i = 2; i < maxn; i++) {
prime[i] = false;
}
for (LL i = 2; i * i < maxn; i++) {
if (prime[i]) {
for (LL j = i * i; j < maxn; j+= i) {
prime[j] = false;
}
}
}
return 0;
}
这个模板比较常用,可以记下来。
至于理解这个模板的话,可以看证明方法:埃式筛素数证明
将素数打好表后,我们就可以开始找符合分解的质因数了。
首先,我们要考虑我们枚举的质因数范围。
这里给出一个数学上的结论对于一个正整数n来说,如果它存在除了1和本身之外的因数,那么一定是sqrt(n)左右成对出现的。
证明:比如15 = 3 * 5
3 和 5 这两个因数是除了1和15的因数,那么他们洽洽在sqrt(n)的左边和右边。
然后我们将这个结论进一步扩展:
对于一个正整数n来说,它除了1和本身以外还有其他因数的话,那么有两种情况:
1.因数全部存在于[2,sqrt(n)]范围内
2.因数存在于[2,sqrt(n)]范围内,但是你还是没有除断,那么就将n添加进去。
然后我们可以枚举[2,sqrt(n)]范围内进行枚举若是质数且能被n整除,将n /= i,继续判断能否除尽,继续循环,这里我使用结构体记录所有因数以及因数个数。
struct factor{
LL x, cnt; //x代表因子,cnt记录该因子的个数
};
LL a = (LL)sqrt(1.0 * n);
for (LL i = 2; i <= a; i++) {
if (prime[i]) {
if (n % i == 0) {
f[num].x = i;
f[num].cnt = 0;
while (n % i == 0) {
f[num].cnt++;
n /= i;
}
num++;
}
}
if (n == 1) break;
}
if (n != 1) {
f[num].x = n;
f[num++].cnt = 1;
}
3.AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 1e6 + 5;
struct factor{
LL x, cnt; //x代表因子,cnt记录该因子的个数
};
bool prime[maxn];
int main() {
for (LL i = 2; i < maxn; i++) {
prime[i] = true;
}
for (LL i = 2; i * i < maxn; i++) {
if (prime[i]) {
for (LL j = i * i; j < maxn; j+=i) {
prime[j] = false;
}
}
}
LL n; //需分解的数
scanf("%I64d", &n);
LL t = n;
factor f[100];
int num = 0;
if (n == 1) printf("%lld=%lld", n,n);
else {
LL a = (LL)sqrt(1.0 * n);
for (LL i = 2; i <= a; i++) {
if (prime[i]) {
if (n % i == 0) {
f[num].x = i;
f[num].cnt = 0;
while (n % i == 0) {
f[num].cnt++;
n /= i;
}
num++;
}
}
if (n == 1) break;
}
if (n != 1) {
f[num].x = n;
f[num++].cnt = 1;
}
printf("%lld=", t);
for (int i = 0; i < num; i++) {
if (i > 0) printf("*");
printf("%lld", f[i].x);
if (f[i].cnt > 1) {
printf("^%lld", f[i].cnt);
}
}
}
return 0;
}
欢迎关注ly’s Blog