前些天看到一下一篇文章:
--------------------------------------------------------------------------
英国大数学家哈代(G.H.Hardy,1877-1947)曾经发现过一种有趣的现象:
153=13+53+33 371=33+73+13 370=33+73+03 407=43+03+73
他们都是三位数且等于各位数字的三次幂之和,这种巧合不能不令人感到惊讶.更为称奇的是,一位读者看过哈代的有趣发现后,竟然构造出其值等于各位数字四(五,六)次幂之和的四(五,六)位数:
1634=14+64+34+44 54748=55+45+75+45+85 548834=56+46+86+86+36+46
像这种其值等于各位数字的 n 次幂之和的 n 位数,称为 n 位 n 次幂回归数.本文只讨论这种回归数,故简称为回归数,人们自然要问:对于什么样的自然数 n 有回归数?这样的 n 是有限个还是无穷多个?对于已经给定的 n ,如果有回归数,那么有多少个回归数?
1986年美国的一位数学教师安东尼.迪拉那(Anthony Diluna)巧妙地证明了使 n 位数成为回归数的 n 只有有限个.
设 An 是这样的回归数,即:
An=a1a2a3...an=a1n+a2n+...+ann (其中 0<=a1,a2,...an<=9)
从而 10n-1<=An<=n9n 即 n 必须满足 n9n>10n-1 也就是 (10/9)n<10n ⑴
随着自然数 n 的不断增大,(10/9)n 值的增加越来越快,很快就会使得 ⑴ 式不成立,因此,满足⑴的 n 不能无限增大,即 n 只能取有限多个.进一步的计算表明:
(10/9)60=556.4798...<10*60=600 (10/9)61=618.3109...>10*61=610
对于 n>=61,便有 (10/9)n>10n
由此可知,使⑴式成立的自然数 n<=60.故这种回归数最多是60位数.迪拉那说,他的学生们早在1975年借助于哥伦比亚大学的计算机得到下列回归数:
一位回归数:1,2,3,4,5,6,7,8,9
二位回归数:不存在
三位回归数:153,370,371,407
四位回归数:1634,8208,9474
五位回归数:54748,92727,93084
六位回归数:548834
七位回归数:1741725,4210818,9800817
八位回归数:24678050,24678051
但是此后对于哪一个自然数 n (<=60)还有回归数?对于已经给定的 n ,能有多少个回归数?最大的回归数是多少?
--------------------------------------------------------------------
这对于我们学计算机的人来说很容易通过编程实现,我也在10分钟内写了一个程序,让它在我的奔三机器上跑。结果让我很郁闷,跑了两个多小时才到7位数。这是我发现原先程序有很多可以提高效率的地方,下面给出我修改后的代码
#include <stdio.h>
int main()
{
long num,total,begin=1,end=9;
long code[]={0,1,2,3,4,5,6,7,8,9}; / /保存i^x,0<=i<=9,1<=x<=60;
int i,n;
char divnum[61],*p;
FILE *fp;
if((fp=fopen("result.txt","w"))==NULL) / /result.txt保存结果,同时在终端上显示
{
printf("Open file error!");
exit(0);
}
for(n=1;n<=60;n++) / /n表示当前数字的位数
{
printf("The %2d group:",n);
fprintf(fp,"The %2d group:",n);
for(num=begin;num<=end;num++)
{
if(num%100000l==0) / /每处理100000个数字刷屏一次
printf("%15ld/b/b/b/b/b/b/b/b/b/b/b/b/b/b/b",num);
sprintf(divnum,"%ld",num); / /分离数字到字符数组
total=0;
for(p=divnum;*p;p++)
total+=code[*p-'0']; / /计算各个位数的n次方和
if(total==num) / /是回归数
{
printf("%ld,",num);
fprintf(fp,"%ld,",num);
fflush(fp);
}
}
for(i=2;i<10;i++) / /由i^x计算i^(x+1)
code*=i;
begin*=10;
end=end*10+9;
printf("/b ->OK! /n"); / /一组数据处理完毕
fprintf(fp,"/b ->OK!/n");
fflush(fp); / /强行写入文件
}
printf("/n/nAll number has been list!/n");
fprintf(fp,"/n/nAll number has been list!/n");
fclose(fp);
return 0;
}
这个程序的效率可能并不是很好,目前我也没有发现更好的方法。但是通过程序计算,我发现上面给出的回归数并不完全,我的计算结果如下:
The 1 group:1,2,3,4,5,6,7,8,9 ->OK!
The 2 group ->OK!
The 3 group:153,370,371,407 ->OK!
The 4 group:1634,8208,9474 ->OK!
The 5 group:54748,92727,93084 ->OK!
The 6 group:548834 ->OK!
The 7 group:1741725,4210818,9800817,9926315 ->OK!
The 8 group:24678050,24678051,88593477 ->OK!
The 9 group:146511208,472335975,534494836,912985153 ->OK!
The 10 group ->OK!
可以发现7位数字少了9926315,8位数字少了88593477。
我的程序没有运行完毕,到第10位后长整形就溢出了,也就说:以上结果中1~9位数字中的回归数都是可靠的,完整的。我机子质量差,跑了半个小时才算完9位数字。