zoukankan      html  css  js  c++  java
  • 【Vijos-P1172】反质数-DFS

    题目大意:一个正整数,如果它的约数个数比所有比它小的正整数的约数个数都大,则称这个数为反质数,求不超过N(1≤N≤2000000000)的最大反质数。

    做法:当初一拿到这题瞬间蒙了,不知道这是什么鬼,后来了解约数定理之后发现这就是个裸的DFS啊!约数定理是指,一个数的约数个数等于它分解质因子后的每个质因子的指数+1的乘积,用一个具体的例子来说,例如1800这个数,分解质因子后得到的式子为2^3*3^2*5^2,2的指数是3,3的指数是2,5的指数是2,因此1800的约数个数为:(3+1)*(2+1)*(2+1)=36个。这个定理可以很容易的用组合数学的方法来证明。然后就可以愉快的DFS了,思路非常简单,从小到大枚举质因子和它的指数,记录下满足条件的最大数字和它的约数个数即可。需要注意的是解的替换,如果当前数字的约数个数比前面求出的解的约数个数大,则必须替换,因为在这种情况下,说明当前数字比已知解更优或已知解不满足条件。如果当前数字的约数个数与前面求出的解的约数个数相等而数字比已知解小,则说明已知解不满足条件,也要替换。可以证明搜索的深度不超过30。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    long prime[21]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
    long long n,maxi=0,maxn=999999999; //maxn,maxi:满足条件的最大数和它的约数个数
    
    void search(long long x,long long s,long long p) //x,s,p:当前数字,当前数字的约数个数和枚举到的质因子序号
    {
      if (s>maxi) {maxi=s;maxn=x;}
      if (s==maxi&&x<maxn) maxn=x;
      if (s<maxi&&x>maxn) return;
      int total=0;
      while(x*prime[p]<n)
      {
        total++;
        x*=prime[p];
        search(x,s*(total+1),p+1);
      }
    }
    
    int main()
    {
      cin >> n;
      
      search(1,1,1);
      
      cout << maxn;
      
      return 0;
    }


  • 相关阅读:
    iptables 增删查改
    在Ubuntu14.04上安装WordPress4搭建技术博客
    Revit 二次开发之 零件
    Revit 二次开发之 结构层次
    revit二次开发之 过滤器二FilteredElementCollector收集器
    Revit二次开发之 动态模型更新(DMU: Dynamic Model Update)功能
    revit二次开发之 过滤器一
    Revit 二次开发之标高参数
    Revit二次开发之 错误
    Visual Studio删除所有的注释和空行
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793945.html
Copyright © 2011-2022 走看看