zoukankan      html  css  js  c++  java
  • 【BZOJ】1053: [HAOI2007]反素数ant

    【题意】记正整数x的因数个数为g(x),当正整数x满足:g(x)>g(i)(0<i<x)时,称x为反素数,求不超过给定N的最大反素数,N<2e9。

    【算法】数论,搜索

    【题解】

    这个问题等价于求1~N中因数最多的最小数字

    反素数有以下性质:

    1.反素数的素因子一定是从2开始的连续素数

    必要性证明:对于A^p1*B^p2,A<C<B,将B更换成C后的数字A^p2*C^p1显然小于原数且因数个数相等,与反素数的定义矛盾。

    2.反素数的素因子指数一定按素因子从小到大的顺序不递增

    必要性证明:对于A^p1*B^p2(p2>p1),将p1和p2交换后的数字A^p2*B^p1显然小于原数且因数个数相等,与反素数的定义矛盾。

    注意:这两条性质不满足充分性

    有了这两条性质,就可以搜索素因子指数的所有情况(素因子至多12个,到31为止),找到因数最多的最小数字。

    dfs(dep,p,sum,num),第dep个素因子,上一个指数为p,因数个数为sum,数字为num。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int prime[15]={0,2,3,5,7,11,13,17,19,23,29,31,33,37,41};
    int n,mx,ans;
    void dfs(int dep,int p,int sum,ll num){
        if(sum>mx||(sum==mx&&num<ans)){
            ans=num;
            mx=sum;
        }
        if(dep>12||num>2e9)return;
        ll s=prime[dep];
        int x=1;
        while(num*s<=n){
            dfs(dep+1,x,sum*(x+1),num*s);
            s*=prime[dep];x++;
        }
    }
    int main(){
        scanf("%d",&n);
        mx=0;ans=n;
        dfs(1,100,1,1);
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    mongodb 报错问题
    Android中Is library配置的作用
    Ubuntu 12.04 中安装和配置 Java JDK
    (转)Android开发把项目打包成apk
    (转)Android--使用Canvas绘图
    Android_Gallery(画廊)
    android组件
    Android中px dpi dip density densityDpi 的相关说明
    (转)Android中px与dip,sp与dip等的转换工具类
    (转)谈谈Android中的Rect类——奇葩的思维
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7989363.html
Copyright © 2011-2022 走看看