版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/82932235
【题目链接】
【思路要点】
- 令 表示满足 的最小的质数, 表示满足 的最大的质数。
- 注意到当 足够大时, 个 可以构成一组解,因为贪心会将其分解为 。事实上,当 时, 个 就可以构成一组解。
- 对于剩余部分,我们可以用暴力打表,或是发现答案的形式一定可以是 的样子,这样,我们可以用 的时间枚举答案。
- 时间复杂度 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 2e5 + 5; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int tot, prime[MAXN], f[MAXN]; void sieve(int n) { for (int i = 2; i <= n; i++) { if (f[i] == 0) prime[++tot] = f[i] = i; for (int j = 1; j <= tot && prime[j] <= f[i]; j++) { int tmp = prime[j] * i; if (tmp > n) break; f[tmp] = prime[j]; } } } int main() { sieve(1e5); prime[0] = 1; int T; read(T); while (T--) { int n; read(n); int a = 0, b = 0; for (int i = 1; i <= tot; i++) if (prime[i] * prime[i] >= n) { a = prime[i]; break; } for (int i = 1; i <= tot; i++) if (prime[i] * prime[i] * prime[i] >= n) { b = prime[i - 1]; break; } int ans = a * b; if (ans < n && b * b >= a && b * b * a >= n) printf("3 %d %d %d\n", ans, ans, ans); else { bool found = false; for (int i = 2; i <= n - 1 && !found; i++) for (int j = i + 1; j <= n - 1 && !found; j++) { int prod = i * j * j, cnt = 0; for (int k = n - 1; k >= 2; k--) while (prod % k == 0) { prod /= k; cnt++; } if (cnt >= 4) { printf("3 %d %d %d\n", i, j, j); found = true; } } if (!found) printf("-1\n"); } } return 0; }