原题:https://pintia.cn/problem-sets/994805342720868352/problems/994805415005503488
题目大意
将一个大整数分解成多个质数的乘积,具体请搜索数论——正整数的唯一分解定理。
解法1(素数筛选和匹配)
筛选法的思路是建议一个大小为maxn
的素数表,假定初始全是素数,然后逐个划掉,即1不是素数,花掉;2是素数,则所有2的倍数均不是素数,花掉;依此类推。还应该注意,整数的一对素因子不可能同时大于sqrt(x)
,即若l
是n
的最大素因子,s
是n
的另一个素因子,则n=l*s≥s*s
,所以整数一定存在素因数小于其算术平方根。
则有如下素数筛选解法:
#include<vector>
#include<iostream>
using namespace std;
typedef long int ll;
const int maxn = 1e4;
vector<int> prime(maxn, 0); // 0表示是素数,1表示不是素数
int main() {
// 建立一个素数表
int i, j;
for (i = 2; i*i < maxn; i++) {
if (prime[i] == 1) continue; // 已经筛选过了
for (j = 2; i*j < maxn; j++)
prime[i*j] = 1; // 剔除掉
}
ll num;
cin >> num;
printf("%ld=", num);
if (num == 1) printf("1\n");
bool state = false; // 表明是否已经输出过元素了
for (i = 2; num >= 2; i++) {
int cnt = 0;// 指数
int flag = 0; // i是否是因子
while (prime[i] == 0 && num % i == 0) {
cnt++; flag = 1;
num /= i;
}
if (flag) { // 是因子
if (state) printf("*");
printf("%d", i);
state = true;
}
if (cnt >= 2) printf("^%d", cnt);
}
system("pause");
return 0;
}
解法2(素数搜索)
基于以下几个特点:
- 整数x存在素因子小于sqrt(x)
- 若找到一个素因子a,则可以在
x/a
下继续寻找
我们有如下找素因子的解法:
for (ll i = 2; i * i <= num; i++) {
while (num % i == 0) { //能够整除
factor[i]++;
num /= i;
}
}
总的解法:
/* 1059 Prime Factors (25 分) */
// 素数因子 整数的质因数分解
/* 1. 整数的素数因子因小于sqrt(x)
* 2. 若找到整数一个素数因子 a, 则在x/a后再继续找
*/
#include<map>
#include<iostream>
using namespace std;
typedef long int ll;
int main() {
ll num;
map<ll, int> factor;
cin >> num;
printf("%ld=", num);
if (num == 1) printf("1\n");
for (ll i = 2; i * i <= num; i++) {
while (num % i == 0) { //能够整除
factor[i]++;
num /= i;
}
}
if (num != 1) factor[num]++;
for (auto iter = factor.begin(); iter != factor.end(); iter++) {
if (iter != factor.begin()) printf("*");
int p = iter->first, k = iter->second;
printf("%ld", p);
if (k != 1) printf("^%d", k);
}
system("pause");
return 0;
}