• 反素数法


    首先了解一点,求解一个数的因子个数。

    假设p[]数组里全部是素数,那么任何一个整数,可以唯一的表示成n=p1^x1*p2^x2*p3^x3.......*pm^xm,那么因子个数便为:(x1+1)*(x2+1)*.....*(xm+1)。

    给定一个整数n,求解1~~n范围内,因子个数最多的那个数,如果相同的话,取较小的。

    这里要认识到一点,因子数最多的那个数,根据我们上面说的,可以由素数的乘积组成。那么我们枚举素数的幂,也就是上面式子上的x1,x2,x3...xm。就可以遍历到1~~n范围内的所有可能解。假设n的取值范围是10^18次方,看起来很大是吧,对于素数2来说,2^60次方就大于10^18次方了,而且我们可以发现,上面的式子中x1>=x2>=x3>=....xm。而最大的那个也最多只有60次枚举,所以说,枚举起来速度是很快的。

    View Code
     1 #include<iostream>
     2 #include<string>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 int prim[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
     7 __int64 n;
     8 __int64 ans; //答案
     9 int complexity; //因子个数
    10 
    11 void dfs(int k,int limited,__int64 now,int com) //目前在第k个素数,最多搜索limited次,now是目前的数,com是目前的因子数
    12 {
    13     if(now>n)
    14         return;
    15     if(com>complexity)
    16     {
    17         complexity=com;
    18         ans=now;
    19     }
    20     if(com==complexity && now <ans)
    21         ans=now;
    22     if(k>15)
    23         return;
    24     int i;
    25     __int64 m=now;
    26     for(i=1;i<=limited;i++)
    27     {
    28         if(m*prim[k]>n)
    29             break;
    30         m=m*prim[k];
    31         dfs(k+1,i,m,com*(i+1));
    32     }
    33 }
    34 
    35 int main()
    36 {
    37     while(scanf("%I64d",&n)==1)
    38     {
    39         complexity=0;
    40         ans=0;
    41         dfs(0,60,1,1);
    42         printf("%I64d %d\n",ans,complexity);
    43     }
    44     return 0;
    45 }
  • 相关阅读:
    老罗的OLLYMACHINE
    VGA寄存器一览表
    常用的I/O地址
    使用VESA示例
    打开A20
    Linux 2.2 Framebuffer Device Programming Tutorial
    Linux驱动
    基于Linux核心的汉字显示的尝试
    汉字的动态编码与显示方案
    AT&T语法(一)
  • 原文地址:https://www.cnblogs.com/ka200812/p/2638800.html
Copyright © 2020-2023  润新知