您的位置:首页 > 其它

完全数

2016-03-24 22:55 253 查看
如果一个数恰好等于它的因子之和,则称此数是完全数。例如: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
=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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: