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;
    }


  • 相关阅读:
    leetcode 29-> Divide Two Integers without using multiplication, division and mod operator
    ros topic 发布一次可能会接收不到数据
    python中的print()、str()和repr()的区别
    python 部分函数
    uiautomatorviewer错误 unable toconnect to adb
    pyqt 不规则形状窗口显示
    appium 计算器demo
    Spring 3.0 注解注入详解
    Spring Autowire自动装配
    restful 学习地址
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793944.html
Copyright © 2011-2022 走看看