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 \le T \le 15)T (1T15),表示数据组数。

接下去有TT组数据,每组数据的第一行有一个正整数n \ (1 \le n \le 100)n (1n100).

第二行有nn个正整数a_1, \ldots, a_n \ (1 \le a_1, \ldots ,a_n \le 2\times 10^9)a1,,an (1a1,,an2×109), 表示这个数列。
输出描述
输出TTTT个数表示每次询问的答案。
输入样例
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 }
View Code

代码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 }
View Code

 

 

posted @ 2016-03-11 19:20  fenicnn  阅读(238)  评论(0编辑  收藏  举报