题目链接:http://codeforces.com/contest/1165/problem/D
题意:现在有n个数,他们都是某一个数的全部因子(不包含这个数本身和1),问能否找到这个数。如果不能输入-1。
解题心得:
- 首先如果这些数是某个数的全部因子,那么排序之后首尾相乘就是这个数,并且排序之后按照对称的方式乘起来应该是相同的。例如 16 16 16的因子有 2 2 2, 4 4 4, 8 8 8。这三个数是关于 4 4 4对称的, 2 ∗ 8 = 4 ∗ 4 2*8=4*4 2∗8=4∗4。
- 还需要验证的一点是找到的这个数是否全部因子都在这 n n n个数中,如果直接对找到的这个数分解因子复杂度是 1 e 6 1e6 1e6并且 t t t组数据会 T L E TLE TLE,这个时候就需要换一个思路,首先要明白的是一个数的因子的因子仍然是这个数的因子,这样就可以对三百个数进行分解,查看分解出来的因子是否全部包含在这 n n n个数之中,这样复杂度就是 300 ∗ 1000 300*1000 300∗1000,即使是 t t t组数据也能过。
#include <bits/stdc++.h>
using namespace std;
typedef complex<double> cp;
typedef long long ll;
const int maxn = 2e5+100;
const double pi = acos(-1);
int t, n;
ll num[maxn];
bool vis[maxn*5];//vis记录n个出现过的数
void init() {
scanf("%d", &n);
for(int i=1;i<=n;i++) {
scanf("%lld", &num[i]);
vis[num[i]] = true;
}
sort(num+1, num+1+n);
}
int main() {
// freopen("1.in.txt", "r", stdin);
scanf("%d", &t);
while (t--) {
init();
ll ans = num[1] * num[n];
for (int i = 1; i <= n; i++) {//检查对称乘起来是否相同,这样可以确定这个数是否存在
if (ans != num[i] * num[n - i + 1]) {
ans = -1;
break;
}
}
if (ans != -1) {//如果找到了这个数需要检验这个数的所有因子是否都在这n个数中
for (int j = 1; j <= n; j++) {//对300个数进行因式分解
ll temp = num[j];
for (int i = 2; i * i <= temp; i++) {
if (temp % i == 0) {
if (!vis[i] || !vis[temp / i]) {
ans = -1;
break;
}
}
}
if (ans == -1) break;
}
}
printf("%lld\n", ans);
for(int i=1;i<=n;i++) vis[num[i]] = false;
}
return 0;
}