题目:
题意:
给定数n,输出两个质数p和q,需满足p * p * q = n
题目保证一定有解
思路:
n一定只有两个因数,且一定为p和q,所以如果其中一个确定了,另外一个也可以确定。
因为n最大是9e18,所以可以考虑找到最小的因数(命名为t),则 t 一定不超过9e18的开立方 。
解释:因为如果三个数中最小的超过了,那么三个数的乘积一定会超过9e18
我们先用线性筛找出3e6范围内的素数,然后for循环遍历找第一个能整除n的素数(命名为 t ),如果
1、( x / t ) % t == 0 ,则说明 t 就是 p
另外一个数即为 x / ( t * t )
2、否则,说明 t 为 q
另外一个数即为 sqrt( x / t )
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define sf(x) scanf("%d", &x);
#define de(x) cout << x << " ";
#define Pu puts("");
const int N = 3e6 + 10;
int n, m, ans;
ll pri[N];
int tot;
bool isp[N];
void init() {
for (int i = 2; i < 3e6; i++) {
if (isp[i] == 0)
pri[++tot] = i;
for (int j = 1; j <= tot && pri[j] * i < 3e6; j++) {
isp[pri[j] * i] = 1;
if (i % pri[j] == 0)
break;
}
}
}
int main() {
int T;
cin >> T;
init();
ll x, t;
ll a, b;
while (T--) {
cin >> x;
for (int i = 1; i <= tot; i++) { // 最小值为不超过3e6的质数
t = pri[i];
if (x % t == 0) {
x /= t;
if (x % t == 0) { // 如果x/t还能整除t,说明为t有两个
// 这些一定要记住,longlong型用cout输出时需要提前用一个变量存储起来,
// 否则一定会输出7e+005 这种形式,导致答案错误
// printf("%lld %lld\n", t, x / (t * t));
// cout << t << " " << x / (t * t) << endl;
a = t;
b = x / t;
cout << a << " " << b << endl;
break;
} else {
// cout << sqrt(x / t) << " " << t << endl;
// printf("%lld %lld\n", fun(x / t), t);
a = sqrt(x);
b = t;
cout << a << " " << b << endl;
break;
}
}
}
}
}