HDU 4133 StrangeStandard【反素数】

题意: 求出 n 以内的最大反素数。

分析: 如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数.

          求[1..N]中最大的反素数–>求约数最多的数

          如果求约数的个数 756=2^2*3^3*7^1

          (2+1)*(3+1)*(1+1)=24

          基于上述结论,给出算法: 按照质因数大小递增顺序搜索每一个质因子,枚举每一个质因子

          剪枝:

         性质一: 一个反素数的质因子必然是从2开始连续的质数.

         因为最多只需要10个素数构造:2,3,5,7,11,13,17,19,23,29

         性质二:p=2^t1*3^t2*5^t3*7^t4…..必然t1>=t2>=t3>=….

#include <stdio.h>
#include <string.h>
#include <math.h>
typedef __int64 INT;
INT rsum;   // 约数的个数
INT rnum;   // 约数最多的数
INT n;      // n 以内的最大反素数
// 事先估算 2*3*..p>n
INT pri[22] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
// 走到 num 这个数,用到了第 k 个素数,num的约数的个数为sum
void getnum(INT num,INT sum,INT k,INT lim)
{
    if(num > n)
        return;
    if(sum > rsum){
        rsum = sum;
        rnum = num;
    }
    else if(sum == rsum && num < rnum){
        rnum = num;     // 取相同约数的最小值
    }
    INT i, p = 1;
    for(i = 1; i <=lim; i++){
        p*=pri[k];
        if(num*p>n)
            break;
        getnum(num*p,sum*(i+1),k+1,i);
    }
}
INT log2(INT n) // 求大于等于log2(n)的最小整数
{
    INT i = 0;
    INT p = 1;
    while(p<n){
        p*=2;
        i++;
    }
    return i;
}
int main()
{
    int ca=1,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%I64d",&n);
        rsum = rnum =0;
        getnum(1,1,0,log2(n));
        printf("Case #%d: %I64d\n",ca++,rnum);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/dream-wind/archive/2012/10/13/2722177.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值