【LOJ2328】「清华集训 2017」避难所

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/82932235

【题目链接】

【思路要点】

  • x x 表示满足 x 2 b x^2\geq b 的最小的质数, y y 表示满足 y 3 < b y^3< b 的最大的质数。
  • 注意到当 b b 足够大时, 3 3 x y x*y 可以构成一组解,因为贪心会将其分解为 x , x , x , y 3 x,x,x,y^3 。事实上,当 b 126 b\geq 126 时, 3 3 x y x*y 就可以构成一组解。
  • 对于剩余部分,我们可以用暴力打表,或是发现答案的形式一定可以是 x , y , y x,y,y 的样子,这样,我们可以用 O ( b 2 ) O(b^2) 的时间枚举答案。
  • 时间复杂度 O ( T b ) O(T*b)

【代码】

#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;
}

猜你喜欢

转载自blog.csdn.net/qq_39972971/article/details/82932235