hdu 5428 The Factor(数论)

The Factor
There is a sequence of n positive integers. Fancycoder is addicted to learn their product, but this product may be extremely huge! However, it is lucky that FancyCoder only needs to find out one factor of this huge product: the smallest factor that contains more than 2 factors(including itself; i.e. 4 has 3 factors so that it is a qualified factor). You need to find it out and print it. As we know, there may be none of such factors; in this occasion, please print -1 instead.

Input
The first line contains one integer T (1≤T≤15), which represents the number of testcases.

For each testcase, there are two lines:

  1. The first line contains one integer denoting the value of n (1≤n≤100).

  2. The second line contains n integers a1,…,an (1≤a1,…,an≤2×109), which denote these n positive integers.

Output
Print T answers in T lines.

Sample Input
2
3
1 2 3
5
6 6 6 6 6

Sample Output
6
4

题目大意:
找出给出的数列乘积的最小的约数,这个约数必须有两个以上因子,比如4的因子是1,2,4,满足,其实就是这个约数能分解成别的数相乘。
解题思路:
既然约数能被分解成别的数相乘,那么分解成的一定是质数,如果不是质数,那么不是质数的还可以再分解,直接要不是质数的就好了。同时一定是只能分解成两个质数,如果是三个质数,那么就可以再去除一个较大的数,剩下的两个的乘积也满足条件,也就是说约数是由两个质数相乘得到的。

既然是由两个质数相乘得到,我们就找出数列中每一个数的质因子(包括它自己),最后找到两个最小的,输出乘积就好了。

具体如何找看代码中的注释:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    cin>>T;
    while(T--)
    {
        long long int n;
        long long int a=2e10+1;
        long long int b=2e10+1;
        cin>>n;
        for(int i=1; i<=n; i++)
        {
            long long  x;
            cin>>x;
            if(x==1) continue;
            bool mark=false;           //判断是不是素数
            bool mark1=false;          //判断是否现在质数大于已经找到的两个质数,如果是,break就好了
            for(int j=2; j<=int(sqrt(x))+1; j++)
            {
                //cout<<j<<endl;
                int x1=x;
                while(x1%j==0)  //如果能整除一个数,要判断是否能再次整除
                {
                    mark=true;
                    if(a<=b&&j<b) b=j;              //覆盖两个数中较大的一个
                    else if(a>=b&&j<a) a=j;
                    else
                    {
                        mark1=true;
                        break;
                    }
                    x1=x1/j;
                    if(x1%j==0) continue;
                    else if(x1>j)         //这个循环不能遍历所有的因子,比如15只能到4,所以当一个数可以除尽的时候,
                    {                    //也要判断它对应的因子,比如3是15的一个因子,与3对应因子的就是5
                        if(a<=b&&x1<b) b=x1;
                        else if(a>=b&&x1<a) a=x1;
                        else
                        {
                            mark1=true;
                            break;
                        }
                    }
                }
                if(mark1) break;
            }
            if(!mark)           //如果一次x1%j都没有,那么这个数是素数
            {
                if(a<=b&&x<b) b=x;
                else if(a>=b&&x<a) a=x;
            }
        }
        if(a==2e10+1||b==2e10+1) cout<<-1<<endl;
        else cout<<a*b<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值