完美数

       我们知道,任何一个自然数的因子中都包含1和它本身,也就是说,任何一个自然数都能被1和它本身所整除,而所有小于它本身的因子称为这个自然数的真因子,例如6的因子包括1、2、3、6,它的真因子则是1、2、3;8的因子包括1、2、4、8,它的真因子则是1、2、4。下面我们给出一个重要的定义:

如果一个自然数的真因子之和等于这个自然数本身,则这个自然数就称为完美数。

例如,6=1+2+3,因此6是完美数,而8不等于1+2+4,因此8不是完美数。

那么对于给定的一个自然数n,如何用计算机程序来判定它是否是完美数呢?

方法一:按照完美数的定义

int perfect1(int n)
{
    int i,sum=0;
    for(int i=1;i<=n/2;i++)
    {
        if(n%i==0)
        {
            sum+=i;
        }
    }
    if(sum==n)
        return 1;
    return 0;
}

方法二:利用欧几里得完美数公式

欧几里得完美数定理

伟大的古希腊数学家欧几里得提出了著名的完美数判定定理,该定理提供了一种求解完美数的更为高效的方法。该定理是说:

如果整数p和2p-1均为素数,则2p-1(2p-1)是完美数。

这里所谓的素数又称为质数,是指除了1和它本身之外,不能被任何其他数所整除的数就称为素数或质数,例如2,3,5,7,11等都是素数。

接下来我们就根据欧几里得完美数定理,设计一个计算机程序来求出更多更大的完美数。通过该定理来求完美数时,首先要解决的关键问题就是素数的判定。

1、素数的判定

根据素数定义

int isPrime1(double n)
{
    double i;
    //fmod()函数可以对浮点型数据进行取模运算
    for(i=2;i<=(int)sqrt(n);i++)
    {
        if(fmod(n,i)==0)
        {
            return 0;
        }
    }
    return 1;
}

根据素数分布求素数
首先看一个关于质数分布的规律:大于等于5的质数一定和6的倍数相邻。例如5和7,11和13,17和19等等;
证明:令x≥1,将大于等于5的自然数表示如下:
··· 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 ···
int isPrime2(double n)
{
    if(n==2||n==3)
          return 1;
    for(int i=5;i<=(int)sqrt(n);i+=5)
    {
        if(n%i==0||n%(i+2)==0)
            return 0;
    }
    return 1;
}

埃拉托斯特尼筛法

过程图像:https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
基本思想:每判断一个素数,都将该素数的倍数去掉
int prime[100];
int isPrime3()
{
    int cnt=0;
    for(int i=2;i<1000;i++)
    {
        if(!prime[i])
        {
            prime[cnt++]=i;
            for(int j=i+i;j<1000;i+=i)
            {
                prime[j]=1;
            }
        }
    }
    cout<<"1-100以内的素数:"<<endl;
    for(int i=0;i<cnt;i++)
    {
        cout<<prime[i]<<" ";
    }
}

接下来就是完美数求解

//当p范围是[2,31]时,完美数有几个
long long perfect2()
{
    long long p,t,x,y;
    for(p=2;p<=31;p++)
    {
        if(isPrime1(p)==1)
        {
            t=1;
            for(int k=1;k<=p;k++)
            {
                t=t*2;
            }
            x=t/2;
            y=t-1;
            if(isPrime1(y)==1)
            {
                cout<<x*y<<endl;
            }
        }
    }
}

作者很懒,完美数涉及到的欧几里得,还有很多知识,感兴趣的可以看一些数论知识,你还会发现更神奇的数学!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值