c++
/*
* 试除法判断质数、分解质因数
* 本次将要介绍关于质数两个比较常见的算法,试除法判断质数和分解质因数
*
* 质数定义:
* 质数,又叫素数,是指一个大于1的自然数,且除了1和它本身外,不能被其他自然数整除的数。换句话说,就是该数除了1 和它本身以外,不再有其他的因数。
*
* 算法 1. 试除法判断质数:
* 算法流程:
* 试除法判断质数是从质数的定义出发,对待判断的数字 x 而言,从 2 -> x - 1,判断是否可以被整除。 O(N) 复杂度。
* 但是考虑到倘若 x 存在因数 a, 那么 b = x / t, b 也是 x 的因数,并且 x = a * b。假设 a != 1 && a != x,
* 那么 a, b 中至少存在一个数字 <= sqrt(x),也就是使用试除法便利因数的时候,最高需要到 sqrt(n),复杂度优化到 O(N ^ 0.5)
* 注意点:
* 需要特判 x == 1 这种情况
*
* 算法 2. 分解质因数
* 问题描述:
* 给定一个正整数 x,现需要将其分解为质因数的乘积形式。
* 朴素算法:
* 首先筛选出素数,而后便利小于等于 x 的素数,将 x 分解,并注意在分解过程中 x 是不断更新变小的。
* 素数塞的复杂度为 O(N) + 分解复杂度 O(N)
* 跳跃方法:
* 我们对 x 因数从小到大分解过程中,即使不预先筛选素数,其实也只有素数被选出来,因为我们分解 x 过程中总是先遇到质数。
* 其次,也不必便利到 x - 1, 因为 sqrt (x) 也除以不了的话,就说明剩余更新的 x 也是一个质数。
* 复杂度 O(log N) + O(sqrt(N)) = O(N ^ 0.5)
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
int n;
// 试除法判断质数
bool is_prime(int x) {
if (x <= 1) { // 这里需要特判一下
return false;
}
double t = sqrt(x);
for (int i = 2; i <= t; i ++ ) { // sqrt(x)
if (x % i == 0) {
return false;
}
}
return true;
}
// 分解质因数
vector<PII> decompose_prime(int x) {
vector<PII> res;
int cnt = 0;
for (int i = 2; i <= sqrt(x); i ++ ) { // sqrt (x)
if (x % i == 0) {
cnt = 0;
while (x % i == 0) { // 注意这里是 while 循环
cnt += 1;
x /= i;
}
res.push_back(PII(i, cnt));
}
}
if (x != 1) { // 如果 x != 1,就说明 x 是剩余的质数
res.push_back(PII(x, 1));
}
return res;
}
int main()
{
scanf("%d", &n);
int x;
while (n -- ) {
scanf("%d", &x);
vector<PII> res = decompose_prime(x);
for (int i = 0; i < res.size(); i ++ ) {
printf("%d %d\n", res[i].first, res[i].second);
}
printf("\n");
}
return 0;
}