题目给出你一个
d
d
d,要求你找出一个数字
y
y
y,找到的
y
y
y至少有四个整数因子并且任意两个因子之间的差至少为
d
d
d。
思路:
首先
1
1
1是任何数字的因子,任何数自己本身也是自己的一个因子,所以我们只需要找到两个差值不小于
d
d
d的数字
x
1
,
x
2
x_1, x_2
x1,x2,并且
m
i
n
(
x
1
,
x
2
)
min(x_1, x_2)
min(x1,x2)与
1
1
1的差值也不小于
d
d
d,那么第四个因子就是
x
1
∗
x
2
x_1*x_2
x1∗x2,也就是我们要找的
y
y
y。所以最终答案就是
y
=
1
∗
(
1
+
d
)
∗
(
1
+
d
+
d
)
y=1*(1+d)*(1+d+d)
y=1∗(1+d)∗(1+d+d)…吗?这个答案看上去没什么问题,但是再看一遍题目,要求任意两个因子之间的差至少为
d
d
d,而
y
y
y可能还有其他的因子,其他的因子的差可能会小于
d
d
d,所以这样是不可以的。
但是这并不能说明这个方法是不可取的,如果取到的
x
1
,
x
2
x_1, x_2
x1,x2除了
1
1
1和它本身没有其他的因子,那么
y
y
y也就不会有除了
1
,
x
1
,
x
2
,
y
1, x_1, x_2, y
1,x1,x2,y其他的因子了。而
x
1
,
x
2
x_1, x_2
x1,x2取质数就可以很好的解决问题了。用质数筛筛出质数,两次二分查找就能找到答案。
AC代码:
#include <cstdio>
#include <algorithm>
typedef long long ll;
const int Maxn = 30005;
bool isPrime[Maxn];
int Prime[Maxn], cnt;
void getPrime(int n) {
isPrime[0] = isPrime[1] = true;
for (int i = 2; i <= n; i++) {
if (!isPrime[i]) {
Prime[cnt++] = i;
}
for (int j = 0; j < cnt && i * Prime[j] <= n; j++) {
isPrime[i * Prime[j]] = true;
if (i % Prime[j] == 0) {
break;
}
}
}
}
void solve() {
int d;
scanf("%d", &d);
int p1 = (int)(std::lower_bound(Prime, Prime + cnt, 1 + d) - Prime);
int p2 = (int)(std::lower_bound(Prime, Prime + cnt, Prime[p1] + d) - Prime);
ll ans = 1LL * Prime[p1] * Prime[p2];
printf("%lld\n", ans);
}
int main() {
getPrime(30000);
int T;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}