zoukankan      html  css  js  c++  java
  • 完全数

    如果一个数恰好等于它的因子之和,则称此数是完全数例如:6=1+2+3,(包含1,但不包括本身)

    首先穷举它的因数,这里优化一下。根据因数的性质,不小于2的自然整数的可能样式:

    2x.....x最大因数=C
    3x.....x最大因数=C
    .............
    优化:根据观察,数C的最大因数(不包括本身)一定小于或等于它的一半,即最大因数<=C/2。这个可以减少穷举的次数。

    for(i=1;i<=C/2;i++)
    if(C%i==0) /*则i是C的因数

    假如在穷举中需要保存完全数的因数,可以存放在数组中..

    /*第一种解法:存因数于数组中*/
    #include <iostream>
    using namespace std;
    int main()
    {
      int a[15];
      int i,C,n,s;
      for(C=2;C<1000;C++)
      {
         n=-1;
         s=C;
         for(i=1;i<=C/2;i++)/*最大因数<=C/2*/
          {
                   if(C%i==0)
                  {      
             n++;/*统计因数个数*/
                     s=s-i;/*循环减去因数*/
                     a[n]=i;/*数组存储因数*/
                  }
          }
           if(s==0)
             {
                cout<<"完全数:"<<C<<endl;
               for(i=0;i<=n;i++)/*打印因数*/
                 cout<<a[i]<<" ";
                 cout<<endl;
              }
      }
    return 0;
    }
    /*第二种解法*/
    /*直接算出结果*/
    
    #include <iostream>
    using namespace std;
    int main()
    {
        int C,i,m;
        for(C=2;C<1000;C++)
            {
                for(m=0,i=1;i<=C/2;i++)
                {
                    if(!(C%i))/*是因数*/
                    m+=i;
                }
            if(m==C)
            cout<<C<<" ";
            }
        return 0;
    }

    补充:2016/3/27号,新的优化方法。
    根据因数出现的形式来观察,比如100这个数:
    100=1*2*4*5*|10|*20*25*50*100,发现100的因数都是成对出现的(左右对称),以100的平方根10为分界线,左边最大的因数,一定不会超过平方根10,所以试商只用小于或等于整数平方根的数即可。(这个也证明了,为什么检测一个数是否为素数,只用小于或等于它的平方根以下的数试商的原因!

    完全数的定义中不包含本身,所以求和时,先将m置为1,当它能被x整除时,再加上它的另一半对称的数即可,即:
    如果C%x==0,则m=m+x+C/x,此外,还有一个特别的地方,如果取的平方根恰好是原数的平方根,最后还要减去一次平方根,因为多加了一次!

    #include <iostream>
    #include <cmath>
    using namespace std;
    int main()
    {
        int C,i,m,v;
        for(C=2;C<1000;C++)
            {
                m=1;
                v=sqrt(C);/*取平方根限定试商范围*/
                for(i=2;i<=v;i++)/*2~sqrt(C)*/
                {
                    if(!(C%i))/*是因数*/
                    {                       
                        m=m+i+C/i;
                    }
                }
                if(C%v==0)
                {
                    m=m-v;
                }
                    if(m==C)
                    cout<<C<<" ";
            }
        return 0;
    }
  • 相关阅读:
    守护线程Daemon的理解
    Activity并行网关和排他网关
    Activity快速入门理解
    java虚拟机内存区域理解
    Maven的使用
    Mybatis拦截器(插件实现原理)
    網絡上好的博客收集
    jdbc 设置连接支持多条sql
    python 多环境安装
    Linux 系统命令
  • 原文地址:https://www.cnblogs.com/tinaluo/p/5317661.html
Copyright © 2011-2022 走看看