The Factor
Accepts: 101
Submissions: 811
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
有一个数列,FancyCoder沉迷于研究这个数列的乘积相关问题,但是它们的乘积往往非常大。幸运的是,FancyCoder只需要找到这个巨大乘积的最小的满足如下规则的因子:这个因子包含大于两个因子(包括它本身;比如,4有3个因子,因此它是满足这个要求的一个数)。你需要找到这个数字并输出它。但是我们知道,对于某些数可能没有这样的因子;在这样的情况下,请输出-1.
输入描述
输入文件的第一行有一个正整数T (1≤T≤15),表示数据组数。 接下去有T组数据,每组数据的第一行有一个正整数n (1≤n≤100). 第二行有n个正整数a1,…,an (1≤a1,…,an≤2×109), 表示这个数列。
输出描述
输出T行T个数表示每次询问的答案。
输入样例
2 3 1 2 3 5 6 6 6 6 6
输出样例
6 4
思路:很巧妙啊哈。。别看每个数那么大,对于每个数字,只有它们的质因子是有用的,所以我们只需要把每个质因子分解,然后对它们排序,然后找出两个最小的相乘就好了。如果所有的所有数字的质因子个数小于2个,那么就是无解。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 110
typedef __int64 ll;
ll a[maxn];
ll res[123456];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
memset(res,0,sizeof(res));
memset(a,0,sizeof(a));
int cnt=0;
for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
for(int i=1;i<=n;i++){
for(int j=2;(ll)j*j<=a[i];j++){ //注意这里是小于等于a[i]; 一开始打错了,导致我查错查了好久
while(a[i]%j==0){
res[cnt++]=j;
a[i]=a[i]/j;
}
}
if(a[i]!=1) res[cnt++]=a[i];
}
sort(res,res+cnt);
if(cnt<2) printf("-1\n");
else{
ll ans=res[0]*res[1];
printf("%I64d\n",ans);
}
}
}