51nod 1060 最复杂的数

把一个数的约数个数定义为该数的复杂程度,给出一个n,求1-n中复杂程度最高的那个数。
 
例如:12的约数为:1 2 3 4 6 12,共6个数,所以12的复杂程度是6。如果有多个数复杂度相等,输出最小的。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 100)
第2 - T + 1行:T个数,表示需要计算的n。(1 <= n <= 10^18)
Output
共T行,每行2个数用空格分开,第1个数是答案,第2个数是约数的数量。
Input示例
5
1
10
100
1000
10000
Output示例
1 1
6 4
60 12
840 32
7560 64
——————————————————————————
这道题就是求不大于n的反素数 反素数有个性质就是质数的次数
质因数越小出现的次数越大 也就是不增
这样之后找18个质数(乘起来超过1e18) 然后这样剪枝就可以过了
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const LL inf=1LL<<60;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int num[19]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
LL T,n,ans,mx;
void dfs(LL now,LL sum,int step,int last){
    if(now>mx) mx=now,ans=sum;
    if(now==mx&&ans>sum) ans=sum;
    for(int i=1;i<=last;i++){
        if(inf/num[step]<sum||sum*num[step]>n) break;
        sum=sum*num[step];
        dfs(now*(i+1),sum,step+1,i);
    } 
}
int main(){
    T=read();
    while(T--){
        ans=0; mx=0;
        n=read();
        dfs(1,1,1,70);
        printf("%lld %lld
",ans,mx);
    }
    return 0;
}
View Code
 
原文地址:https://www.cnblogs.com/lyzuikeai/p/7448028.html