zoukankan      html  css  js  c++  java
  • 反素数小结

     反素数

    反素数的定义:对于任何正整数,其约数个数记为,例如,如果某个正整数满足:对任意的正整

     数,都有,那么称为反素数。

    从反素数的定义中可以看出两个性质:

    (1)一个反素数的所有质因子必然是从2开始的连续若干个质数,因为反素数是保证约数个数为的这个数尽量小

    (2)同样的道理,如果,那么必有

    其实知不知道反素数这个东西倒是无所谓。关键是理解这两条性质是怎么得出来的。理解了这个,那么相关的题就往这方面想就行了。

    这里解释一下这两条性质:定义里的是严格小于,这个很重要,这就决定了一个数如果是反素数,那么它一定是满足条件的最小的数。

    那么要找反素数,一定是按着这两条性质来找才能保证是最小的。

    例题:

    Codeforces#27(div2)E:

    http://codeforces.com/problemset/problem/27/E

     题意:给一个正整数n,输出有n个因子的最小的数。

    就是按那两条思路来dfs。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<algorithm>
    #include<stack>
    #include<queue>
    using namespace std;
    #define INF 1000000000
    #define eps 1e-8
    #define pii pair<int,int>
    #define LL long long int
    #define ULL unsigned long long int
    int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
    /*素数一直连乘,乘到47就不能再往下乘了,否则就超了unsigned long long int了*/
    int n;
    ULL ans=1000000000000000009;
    void dfs(int pi,int num,int limit,ULL temp)
    /*pi表示当前用到第几个素数,num表示当前数的因子个数,
    limit表示当前用到的这个素数最多能用几次方,temp表示当前数的大小。*/
    {
        if(num>n) return;
        else if(num==n)
        {
            ans=min(ans,temp);
            return;
        }
        else
        {
            ULL t=prime[pi];
            for(int i=1;i<=limit;i++,t*=prime[pi])
            {
                dfs(pi+1,num*(i+1),i,temp*t);
            }
        }
    }
    int main()
    {
        //freopen("in6.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        scanf("%d",&n);
        dfs(0,1,60,1);
        printf("%I64d
    ",ans);
        return 0;
    }
    View Code

     ZOJ 2652 

    这道题和上道题一样的,旧瓶装新酒。我之前过了,今天又写了一遍怎么都得不到正确结果,原来是递归函数传参数时改变了原来的值。以前真没有注意到这个易错点。经验值+1。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<algorithm>
    #include<stack>
    #include<queue>
    using namespace std;
    #define INF 1000000000
    #define eps 1e-8
    #define pii pair<int,int>
    #define LL long long int
    #define ULL unsigned long long int
    LL n,ans,anum;
    long long prime[16]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
    /*先用计算器算一下乘到哪个就够了,避免下面不必要的计算。*/
    void dfs(LL pi,LL limit,LL num,LL temp)
    {
        if(temp>n) return;
        else
        {
            if(num>anum)
            {
                anum=num;
                ans=temp;
            }
            else if(num==anum&&temp<ans)
            {
                ans=temp;
            }
            LL t=(LL)prime[pi];
            for(LL i=1; i<=limit; i++,t*=(LL)prime[pi])
            {
                if(temp*t>n)break;//
                else
                    dfs(pi+1,i,num*(i+1),temp*t);
                /*这里犯了一个错误,导致一直WA而找不到bug。
                我把这句写成了dfs(pi+1,i,num*(i+1),temp*=t);
                这个错误非常典型!在递归调用函数时,我要传入temp*t的值,
                但是如果这么写,当前函数的这一层的temp也变了!而此时for循环
                可能还没有结束,temp的值变了肯定会导致错误。
                包括第一个参数就得写成pi+1而不能写成pi++也是一样的道理。*/
                /*这使我认识到了一个重要点:注意递归调用函数传递参数时,不要改变原参数的值!!!*/
            }
        }
    }
    int main()
    {
        //freopen("in7.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        while(scanf("%I64d",&n)==1)
        {
            ans=1;
            anum=1;
            dfs(0,51,1LL,1LL);
            printf("%I64d
    ",ans);
        }
        //fclose(stdin);
        //fclose(stdout);
        return 0;
    }
    View Code
  • 相关阅读:
    查看crontab的日志记录定位定时任务问题
    Latex 表格内公式换行方法
    C语言中qsort函数用法
    7 种常用的排序算法-视觉直观感受
    Ubuntu下如何安装YouCompleteMe插件
    Linux下非root用户如何安装软件
    系统进化树-原理介绍及软件使用
    LaTeX 页眉页脚的设置
    TEXshade教程- 多重比对着色软件包
    easyUI自带的时间插件日期选择、月份选择、时间选择的使用
  • 原文地址:https://www.cnblogs.com/zywscq/p/3935771.html
Copyright © 2011-2022 走看看