51nod 1060 (因子最多数)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Feynman1999/article/details/82355621

因子个数最多的数

实际上,这样的数称为反素数:

img

即给定 N ,求 [ 1 , N ] 之间最大的反素数(即拥有因子数目最多的数)

性质:

No.1 一个反素数的质因子必然是从2开始连续的质数。
No.2 p=2^t1 x 3^t2 x 5^t3 x 7^t4…..必然t1>=t2>=t3>=….

暴力dfs 时间复杂度大概几个log

//51nod 1060
#include<bits/stdc++.h>
using namespace std;

typedef unsigned long long ll;

int prime[60];

bool is_prime(ll x)
{
    for(int i=2;i*i<=x;++i){
        if(x%i==0) return false;
    }
    return true;
}

int tot;
void init()
{
    tot=0;
    for(int i=2;i<2000&&(tot<20);++i){
        if(is_prime(i)){
            prime[++tot]=i;
        }
    }
}

ll ans,res;
ll up;

void dfs(int last,ll cur,ll num,int pre)//last 是最后一个访问的素数下标  cur是当前数 num是当前数的约数个数   pre是上一次的指数
{
    if(last>=tot) return ;
    if(num>ans){
        res=cur;//当前数
        ans=num;//约数个数
    }
    else if(num==ans){
        res=min(res,cur);
    }
    for(int i=1;i<=61 && i<=pre;++i){//枚举指数
        if(cur<=up/prime[last+1]){
            //cout<<cur<<endl;
            cur*=prime[last+1];
            dfs(last+1,cur,num*(i+1),i);
        }
        else break;
    }
}

int main()
{
    init();
    //cout<<tot<<endl;
    //for(int i=1;i<=tot;++i) cout<<prime[i]<<" ";
    int t;
    cin>>t;
    while(t--)
    {
        ans=0;
        cin>>up;
        dfs(0,1,1,61);
        cout<<res<<" "<<ans<<endl;//该数和因子数目   若因子数目相同则输出最小的数
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Feynman1999/article/details/82355621
今日推荐