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

    题目大意

      如果一个大于等于$1$的正整数 ,满足所有小于$n$且大于等于$1$的所有正整数的约数个数都小于$n$的约数个数,则$n$是一个反素数。比如:$1$,$2$,$4$,$6$,它们都是反素数。

      输入一个$n$($1 leqslant n leqslant 10^{9}$),请你计算不大于$n$的最大反素数。

    题解

      我们知道,对于任意一个正整数$a$,有

      $$a = prod_{i = 1}^{k} p_{i}^{t_{i}}$$

      (其中${ p_{i} }$为质数集合。)

      则$a$的约数个数为$prod_{i = 1}^{k} (t_{i} + 1)$。

      我们只需要搜索${ t_{i} }$即可。

      显然暴搜会超时,我们要加一下优化:

      首先,根据贪心容易得到对于${ t_{i} }$,有$t_{i} geqslant t_{i + 1}$($1 leqslant i < k$)。

      为什么呢?其实我们可以举一个最简单的例子。

      $4 = 2 imes 2$,$6 = 2 imes 3$。显然$4$和$6$的约数个数相等,但$4 < 6$,所以$4$是反素数,而$6$不是。

      所以我们可以根据这个特性来剪枝。

      然后。根据上面我们也可以在筛质数的时候减少枚举量,也就是说如果当前$prod_{i = 1}^{k} p_{i} > n$,那我们就不用求出大于$p_{k}$的质数了。(当然我们也可以直接打个质数表)

    #include <iostream>
    #include <cmath>
    
    #define MAX_SQRT_N 45000
    
    using namespace std;
    
    int n;
    int p[MAX_SQRT_N], tot;
    bool f[MAX_SQRT_N];
    int maxcnt, ans;
    
    void DFS(int idx, int cnt, int last, int num)
    {
        if(cnt > maxcnt || cnt == maxcnt && num < ans)
        {
            maxcnt = cnt;
            ans = num;
        }
        if(idx > tot || !last) return;
        for(int i = 0; i <= last; ++i)
        {
            DFS(idx + 1, cnt * (i + 1), i, num);
            if((long long)num * p[idx] > n) break;
            else num *= p[idx];
        }
        return;
    }
    
    int main()
    {
        cin >> n;
        int tmp = 1;
        for(int i = 2; i <= n; ++i)
        {
            if(!f[i]) 
            {
                if((long long)tmp * i > n) break;
                tmp *= i;
                p[++tot] = i;
            }
            for(int j = 1; (long long)i * p[j]<= n; ++j)
            {
                f[i * p[j]] = true;
                if(!(i % p[j])) break;
            }
        }
        DFS(1, 1, 31, 1);
        cout << ans;
        return 0;
    } 
    参考程序
  • 相关阅读:
    【力扣】两个数组的交集
    【编译原理课程设计】词法分析程序设计
    【力扣14】最长公共前缀
    【力扣20】有效的括号
    【力扣26】删除排序数组中的重复项
    【力扣13】罗马数字转整数
    【力扣9】回文数
    【力扣7】整数反转
    【力扣1】两数之和
    golang micro client 报错500 {"id":"go.micro.client","code":408,"detail":"call timeout: context deadline exceeded","status":"Request Timeout"}
  • 原文地址:https://www.cnblogs.com/kcn999/p/11270410.html
Copyright © 2011-2022 走看看