zoukankan      html  css  js  c++  java
  • 反素数

    问题描述:

    对于任何正整数x,起约数的个数记做g(x).例如g(1)=1,g(6)=4.

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

    现在给一个N,求出不超过N的最大的反素数.

    比如:输入1000 输出 840

    思维过程:

    求[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>=....

     

    View Code
     1 typedef __int64 INT;
     2 INT bestNum;   //约数最多的数
     3 INT bestSum;   //约数最多的数的约数个数
     4 const int M=1000; //反素数的个数 
     5 INT n=500000;//求n以内的所有的反素数
     6 INT rprim[M][2];
     7 //2*3*5*7*11*13*17>n,所以只需考虑到17即可
     8 INT prim[14]={2,3,5,7,11,13,17,19,23,29};  
     9 
    10 //当前走到num这个数,接着用第k个素数,num的约数个数为sum,
    11 //第k个素数的个数上限为limit
    12 void getNum(INT num,INT k,INT sum,INT limit)  {
    13      if(num>n)return;
    14     if(sum>bestSum){
    15         bestSum = sum;
    16         bestNum = num;
    17     }else if(sum == bestSum && num < bestNum){  //约数个数一样时,取小数
    18         bestNum = num;
    19     }
    20     if(k>=7) return; //只需考虑到素数17,即prim[6]
    21   
    22     for(INT i=1,p=1;i<=limit;i++){   //素数k取i个
    23         p*=prim[k];
    24         getNum(num*p,k+1,sum*(i+1),i);
    25     }
    26 }
    27 
    28 INT log2(INT n){   //求大于等于log2(n)的最小整数
    29     INT i = 0;
    30     INT p = 1;
    31     while(p<n){
    32         p*=2;
    33         i++;
    34     }
    35     return i;
    36 }
    37 
    38 int getrprim(){//反素数的个数
    39     int i = 0;
    40     while(n>0){
    41         bestNum = 1;
    42         bestSum = 1;
    43         getNum(1,0,1,log2(n));
    44         n = bestNum - 1;
    45         rprim[i][0]=bestNum;
    46         rprim[i][1]=bestSum;
    47         i++;
    48     }
    49     return i;    
    50 }

     

  • 相关阅读:
    命令拷屏之网络工具
    PHP 设计模式 笔记与总结(1)命名空间 与 类的自动载入
    Java实现 计蒜客 1251 仙岛求药
    Java实现 计蒜客 1251 仙岛求药
    Java实现 计蒜客 1251 仙岛求药
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 LeetCode 143 重排链表
    Java实现 LeetCode 143 重排链表
  • 原文地址:https://www.cnblogs.com/tiankonguse/p/2613877.html
Copyright © 2011-2022 走看看