p-完全数

设正整数a的小于其本身的真因数之和为s,定义 p(a)=s/a 为整数a的因数比;

事实上,完全数是因数比为1的整数。例如 p(6)=1 ,6为完全数;

整数的因数比为某一大于1的整数p,则称该整数为p-完全数。例如p(120)=2,则120为 2-完全数;

试搜索指定区间 [x,y] 中的完全数与 p-完全数。若区间中没有完全数与 p-完全数,探求区间中哪一个整数的因数比最接近某一正整数;

1.说明:

为了求整数a的真因数和s,设置 k(2~sqrt(a))循环枚举,如果k是a的因数,则a/k也是a的因数,通过迭代 s=s+k+a/k,求取因数和 s;

如果a=b*b,显然k=b,a/k=b,此时k=a/k,而因数b只有一个,所以此时必须从和s中减去一个b,这样避免重复计算的处理是必要的;

*设置min存储因数比与正整数差值的最小值,通过计算s,t=s/a及与正整数d的最小差距c=t-d(c>=0):

  • 若c=0,此时的因数比t为正整数,通过数组p、q存储a及其因数比;
  • 若c>0,通过与min比较求取因数比最接近正整数d;

2.程序设计:

#include<stdio.h>
#include<math.h>
int main()
{
   double a,a1,s,b,c,d,d1,k,t,t1,x,y,p[10],q[10],min;
   int j,m=0;
   min=1.0;
   printf("请输入区间x,y:");
   scanf("%d,%d",&x,&y);
   for(a=x;a<=y;a++)  /*枚举区间内所有的整数a*/
   {
      s=1;
      b=floor(sqrt(a));
      for(k=2;k<=b;k++)  /*试商寻求a的因数k*/
         if(fmod(a,k)==0)
            s=s+k+a/k;  /*k与a/k都是a的因数,求和*/
      if(a==b*b)
         s=s-b;  /*如果a=b²,去掉重复因数b*/
      t=s/a;
      d=floor(t);
      c=t-d;
      if(c==0)
      {
         m++;
         p[m]=a;
         q[m]=t;
      }
      else if(c>0.5)
      {
         c=1-c;
         d=d+1;
      }
      if(t>0.5&&c<min)  /*比较求因数比最接近的整数*/
      {
         min=c;
         a1=a;
         t1=t;
         d1=d;
      }
   }
   if(m>0)
      for(j=1;j<=m;j++)  /*逐一输出p-完全数*/
         printf("  p(%.0f)=%.0f",p[j],q[j]);
   else
      printf("  %.0f的因数比%.4f最接近正整数%.0f。\n",a1,t1,d1);
}

3.程序运行示例及其注意事项:

请输入区间x,y:100,10000
  p(120)=2  p(496)=1  p(672)=2  p(8128)=1
请输入区间x,y:10000,20000
  16384的因数比0.9999最接近正整数1。

注意:设参数y的数量级为n,双重循环的运算量为 n^(3/2),即算法的时间复杂度为 O(n^(3/2))

由程序还可以得因数比为3的3-完全数,如p(30240)=3,p(32760)=3;
改进程序还可以探求到因数比为4的4-完全数,如p(518666803200)=4;

那么,是否存在5-完全数或6-完全数?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值