磊哥的密码箱(搜索)

题目描述
磊哥有个密码箱,里面装的都是令磊哥羞羞的东西。
箱子的密码是[1,n]里面的约数最多的数的约数数目。
磊哥的女朋友想知道磊哥到底装的是什么东西?她需要你的帮助。

输入
输入一个整数T,表示有T个测试数据
下面T行,每行输入一个正整数n。

输出
对每个n,输出对应一行一个正整数表示[1,n]里最多约数的数的约数个数。

样例输入
2
13
9

样例输出
6
4

提示
100%的数据满足:1 ≤ n ≤ 1,000,000,000,000,000,000.

思路
根据约数个数定理可知
对于一个大于1正整数n可以分解质因数: 在这里插入图片描述
则n的正约数的个数就是 在这里插入图片描述
其中a1、a2、a3…ak是p1、p2、p3,…pk的指数。
又因为可推出当pi 单调递增时 ai单调递减
所以每次pi向上递推时,其ai必定小于ai-1
由此可进行搜索得出答案

代码实现

#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int N=110;
const int mod=1e9+7;
const double eps=1e-10;
ll ans,n;
int pre[100]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61};
ll quickpow(ll a,ll b)
{
    ll sum=1;
    while(b)
    {
        if(b&1) sum*=a;
        a*=a;
        b>>=1;
    }
    return sum;
}
void dfs(ll cnt,ll tot,ll val,int len)
{
    if(val>n) return ;
    ans=max(ans,tot);
    for(int i=1;i<=len;i++)
    {
        ll temp=quickpow(pre[cnt],i);
        if(temp>n/val) return ;
        dfs(cnt+1,tot*(i+1),val*temp,i);
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld",&n);
        ans=0;
        dfs(1,1,1,18);
        printf("%lld\n",ans);
    }
    return 0;
}

你可能感兴趣的:(搜索)