守形数

来源:互联网 发布:返利网淘宝购物返多少 编辑:程序博客网 时间:2024/04/29 20:11

若正整数n是它平方数的尾部,则称n为守形数,又称同构数

例如,6是其平方数36的尾部,76是其平方数5776的尾部,6与76都是守形数;

探讨搜索指定区间内的守形数,进而搜索指定n位守形数;

区间守形数

试探求指定区间 [x,y] 内的所有守形数;

1.说明:

对指定区间 [x,y] 内的每一个整数a(约定a>1),求出其平方数s;
计算a的位数w,同时计算 b=10^w,a的平方s的尾部 c=s%b
比较整数a与其平方数的尾部c,若a=c,则输出守形数;

2.程序设计:

#include<stdio.h>int main(){     long a,b,c,k,m,s,x,y;   printf("请输入区间的上下限整数x,y:");   scanf("%ld,%ld",&x,&y);   m=0;   for(a=x;a<=y;a++)   {      s=a*a;    /*计算a的平方数s*/      b=1;k=a;      while(k>0)      {         b=b*10;         k=k/10;      }      c=s%b;   /*c为a的平方数s的尾部*/      if(a==c)      {         m++;         printf("%ld^2=%ld \n",a,s);      }   }   printf("区间[%ld,%ld]中,共以上%ld个守形数。\n",x,y,m);}

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

请输入区间的上下限整数x,y:10,1000025^2=62576^2=5776376^2=141376625^2=3906259376^2=87909376区间[10,10000]中,共以上5个守形数。

n位守形数

以上程序设计搜索到 2个 2位守形数、2个 3位守形数、1个 4位守形数,守形数的个位数字为“5”或“6”;

试探索一般n位守形数;

1.说明:

为了求更多位数的守形数,可应用守形数的性质:一个m位守形数的尾部k(1<=k<=m-1)位数也是一个高位可能为“0”的守形数

道理很简单:a是一个m位数,a的平方数尾部的k位仅由a的尾部k位决定而与a的其他位无关

实施易知一位守形数有3个:1、5、6,则二位守形数的个位数字只可能是1、5、6这三个数字,根据这一思路,我们可应用递推求解;

设置数组 a[k] 存储守形数的第k位:守形数的个位数字a[1]选取d(1~9),a[k](k>1)选取j(0~9),同时设置b数组存储计算平方的中间值,设置c数组存储计算守形数的平方值,利用 “竖式乘模拟” 计算平方数;
通过比较若有 a[i]=c[i](i=1,2,……,k)成立,则k位守形数确立,继续递推下一位,直至n位打印输出;

2.程序设计:

#include<stdio.h>int main(){   int n,d,k,j,i,t,m,w,z,u,v,a[500],b[500],c[500];   printf("请输入整数n:");   scanf("%d",&n);   for(d=1;d<=9;d++)   {      for(k=1;k<=499;k++)      {         a[k]=0;         b[k]=0;         c[k]=0;      }      a[1]=d;  /*给守形数个位数赋值*/      for(k=2;k<=n;k++)      {         for(j=0;j<=9;j++)         {            a[k]=j;  /*探索守形数的第k位a(k)选数字j*/            v=0;            for(i=1;i<=k;i++)               c[i]=0;            for(i=1;i<=k;i++)            {               for(z=0,t=1;t<=k;t++)               {                  u=a[i]*a[t]+z;                  z=u/10;                  b[i+t-1]=u%10;  /*计算中间结果存于b数组*/               }               for(w=0,m=i;m<=k;m++)               {                  u=c[m]+b[m]+w;  /*计算平方存于c数组*/                  w=u/10;                  c[m]=u%10;               }            }            for(i=1;i<=k;i++)               if(a[i]!=c[i]) /*出现不同数字时继续,a[k]选下一个数字*/                  v=1;            if(v==0)               break;         }      }      if(v==0&&a[n]!=0)  /*输出n位守形数结果*/      {         printf("%d结尾的%d位守形数:",a[1],n);         for(k=n;k>=1;k--)            printf("%d",a[k]);         printf("\n");      }   }}

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

请输入整数n:305结尾的30位守形数:1066199773922562599182128906256结尾的30位守形数:893380022607743740081787109376

注意:以上结果中“5结尾的30位守形数”的第29位为“0”,如果输入n=29,程序运行结果中就没有5结尾的29位守形数。事实上“29位守形数”是存在的,只是其最高位为“0”而已。

  • 变通:

更为明确地刻画出递推进程,建议把以上程序中“输出n位守形数结果”改为“输出k位守形数结果”,即在k循环内加入以下输出程序段:

if(v==0&&a[k]!=0)  /*输出k位守形数结果*/{   printf("%d结尾的%d位守形数:",a[1],k);   for(j=k;j>=1;j--)      printf("%d",a[j]);   printf("\n");}

请观察对应n=30的程序输出结果- -

0 0
原创粉丝点击