HDU 5428 The Factor 分解因式
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5428
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
题解:
对每个数分解素因子,找其中最小的两个(可以相等)相乘就是结果(这个数可以很大,所以要long long输出。
对一个小于等于n的数分解素因数的时间复杂度为sqrt(n)(你用<=sqrt(n)的数去筛,筛完之后最后的一个数要么是1要么是一个质数,这个很好证明),所以暴力解这道题的时间复杂度就为100*sqrt(2*10^9)<10^7,即时间复杂度为o(10^7),完全够解这道题。
代码1:
预处理,先筛出sqrt(n)以内的素数,再用这些素数去分解素因数。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 1e5 + 10; 8 typedef long long LL; 9 10 int n; 11 int p[maxn], tot; 12 int tot_f; 13 int fac[maxn]; 14 15 16 int sift[maxn]; 17 void prepare() { 18 //这个预处理能将时间复杂度降到o(100*sqrt(n)/(ln sqrt(n)))即o(10^6) 19 memset(sift, 0, sizeof(sift)); 20 for (int i = 2; i*i <= maxn; i++) { 21 if (sift[i] == 0) { 22 for (int j = i * 2; j <= maxn; j += i) { 23 sift[j] = 1; 24 } 25 } 26 } 27 tot = 0; 28 for (int i = 2; i<maxn; i++) if (sift[i] == 0) { 29 p[tot++] = i; 30 } 31 } 32 33 void init() { 34 tot_f = 0; 35 } 36 37 int main() { 38 prepare(); 39 int tc; 40 scanf("%d", &tc); 41 while (tc--) { 42 init(); 43 scanf("%d", &n); 44 while (n--) { 45 int x; 46 scanf("%d", &x); 47 for (int i = 0; i<tot && p[i] < x; i++) { 48 while (x%p[i] == 0) { 49 fac[tot_f++] = p[i]; 50 x /= p[i]; 51 } 52 } 53 if (x != 1) fac[tot_f++] = x; 54 } 55 if (tot_f>1) { 56 sort(fac, fac + tot_f); 57 printf("%lld\n", (LL)fac[0] * fac[1]); 58 } 59 else { 60 printf("-1\n"); 61 } 62 } 63 return 0; 64 }
代码2:
直接分解因式
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 1e5 + 10; 8 typedef long long LL; 9 10 int n; 11 int fac[maxn],tot_f; 12 13 void init() { 14 tot_f = 0; 15 } 16 17 int main() { 18 int tc; 19 scanf("%d", &tc); 20 while (tc--) { 21 init(); 22 scanf("%d", &n); 23 while (n--) { 24 int x; 25 scanf("%d", &x); 26 for (int i = 2; i*i<=x; i++) { 27 while (x%i == 0) { 28 fac[tot_f++] = i; 29 x /= i; 30 } 31 } 32 if (x != 1) fac[tot_f++] = x; 33 } 34 if (tot_f>1) { 35 sort(fac, fac + tot_f); 36 printf("%lld\n", (LL)fac[0] * fac[1]); 37 } 38 else { 39 printf("-1\n"); 40 } 41 } 42 return 0; 43 }