zoukankan      html  css  js  c++  java
  • P1463 [POI2002][HAOI2007]反素数

    Link

    P1463 [POI2002][HAOI2007]反素数

    Solve

    不知道为什么这道题会变成省选的基础打表

    通过分析题意,能得出三个引理

    引理1

    (1)$N$中的最大的反质数,就是$1$(N)中约数个数最多的数中最小的一个 。

    引理2

    1~N中任何的不同质因子都不会超过10个,且所有质因子的指数总和不超过30。

    引理3

    x的质因子是连续的若干个最小的质数,并且质数单调递增。

    三个引理的证明就不给了,可以感性理解一下

    综上所述,我们可以使用DFS尝试搜索前10个质数的指数,并满足指数递减、总乘积不超过N,同时记录约数的个数。
    在这两个限制条件下,搜索量实际非常小,每当搜索出一个满足条件的整数的时候,我们就按照性质一的结论更新答案,最终得到约数个数最多的数中最小的一个。

    Code

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #define ll long long
    
    using namespace std ;
    
    int pri[15] = {0,2,3,5,7,11,13,17,19,23,29,31};
    //最小的11个质数 
    ll best = -1 , num = -1 ;
    //万一答案是0呢? 
    int n ;
    
    void dfs(ll x  , int rest , int m, int up)
    //x为当前数字的大小,m为当前数字约数的个数
    //rest为当前质数的编号,up为小于三十的当前指数和
    {
        if(m > best || (m == best && x < num))
            num = x , best = m ;
            //根据性质一的更新答案过程 
        ll ans = x ;
        int i = 0 ;
        while(i < up)
        {
            ++ i ;
            if(n / ans < pri[rest]) 
            //保证总乘积不超过N 
                return ;
            int kkk = m * (i + 1 ) ;
            ans *= pri[rest] ;
            if(ans <= n)
                dfs(ans , rest + 1 , kkk , i) ;
                //保证了质数的单调递减 
        }
        //加上这两个搜索的剪枝,就会感到dfs快的飞起  哈哈哈 
    }
    
    int main()
    //及其卑微的主函数 
    {
        scanf("%d" , &n) ;
        dfs(1 , 1 , 1 , 30);
        printf("%lld
    " , num);
    }
    
  • 相关阅读:
    样式超出设定宽度显示显示省略号
    客户端存在潜在危险request.from
    MenuStrip如何设置快捷键
    SVN的使用方法
    长串英文字符不换行的解决办法
    thickbox使用
    System.Web.UI.UserControl”,因此此处不允许
    C#中实现拖动无边框Form窗体和窗体的起始位置
    (转)Altera Forum精彩问答汇总
    (转)如何以32 bit的方式存取SDRAM?
  • 原文地址:https://www.cnblogs.com/martian148/p/13811157.html
Copyright © 2011-2022 走看看