zoukankan      html  css  js  c++  java
  • zoj 2562 More Divisors 反素数

    思路:

    对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.

    如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数.

    现在给一个N,求出不超过N的最大的反素数.

    比如:输入1000 输出 840

    思维过程:

    求[1..N]中约数在大的反素数-->求约数最多的数

    如果求约数的个数 756=2^2*3^3*7^1

    (2+1)*(3+1)*(1+1)=24

    基于上述结论,给出算法:按照质因数大小递增顺序搜索每一个质因子,枚举每一个质因子

    为了剪枝:

    性质一:一个反素数的质因子必然是从2开始连续的质数.

    因为最多只需要10个素数构造:2,3,5,7,11,13,17,19,23,29

    性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1562

    代码如下:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 #include<iomanip>
     5 #include<cmath>
     6 #include<cstring>
     7 #include<vector>
     8 #define ll long long
     9 #define mod 1000000007
    10 using namespace std;
    11 int prime[16]={1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
    12 ll n,mans,msum;
    13 void dfs(ll num,int k,ll sum,ll limit)
    14 {
    15     if(msum<sum){
    16         mans=num;
    17         msum=sum;
    18     }
    19     if(msum==sum&&mans>num) mans=num;
    20     if(k>15) return;
    21     ll t=num;
    22     for(int i=1;i<=limit;i++){
    23         if(t*prime[k]>n) break ;
    24         t=(ll)t*prime[k];
    25         dfs(t,k+1,(ll)sum*(i+1),i);
    26     }
    27 }
    28 int main(){
    29     while(scanf("%lld",&n)!=EOF){
    30         mans=n;msum=0;
    31         dfs(1,1,1,50);
    32         printf("%lld
    ",mans);
    33     }
    34     return 0;
    35 }
    View Code

  • 相关阅读:
    硬件调试软件
    ICMP(Internet Control Message Protocol)
    算法网站
    下载安装
    netcat 实现端口转发
    mqtt 连接工具
    Linux(CentOS7)安装zip、unzip命令
    awk 两个字符串互换位置
    创建一个swift项目
    屏幕录制
  • 原文地址:https://www.cnblogs.com/xin-hua/p/3287346.html
Copyright © 2011-2022 走看看