前兩天在網上看了一篇關於迴歸數的文章。看完後也想自己實現一個尋找迴歸數的演算法。
首先介紹一下迴歸數,以下是摘錄了百度百科的
【迴歸數猜想】
英國大數學家哈代(G.H.Hardy,1877-1947)曾經發現過一種有趣的現象:
153=1^3+5^3+3^3 371=3^3+7^3+1^3 370=3^3+7^3+0^3 407=4^3+0^3+7^3
*註: 1^3代表1的3次方。其他類同。
他們都是三位元且等於各位元字的三次冪之和,這種巧合不能不令人感到驚訝.更為稱奇的是,一位讀者看過哈代的有趣發現後,竟然構造出其值等於各位元字四(五,六)次冪之和的四(五,六)位元:
1634=1^4+6^4+3^4+4^4 54748=5^5+4^5+7^5+4^5+8^5 548834=5^6+4^6+8^6+8^6+3^6+4^6
像這種其值等於各位元字的 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
看了上面的文章,覺得用電腦來尋找迴歸數應該不是很難,由此我寫了如下的演算法來尋找迴歸數:
#include <iostream>
#include <math.h>
using namespace std;
//////////////////////////////////////////////////////////////////////////
//find back number
#define MAX_INT 2147483647
void FindBackNumber(int nValue)
{
for (int j = 1; j< MAX_INT; j++)
{
int nBitCount = (int)log10((double)j);
nBitCount++;
if(nBitCount> nValue)
{
return;
}
int m = 0;
int n = j;
while (n !=0)
{
m += (int)pow((double)(n%10),nBitCount);
n /= 10;
}
m += (int)pow((double)(n%10),nBitCount);
if(j == 153)
{
int a = 0;
}
if(m == j)
{
printf_s("%d is a back number;\r\n",j);
}
}
}
int main()
{
//////////////////////////////////////////////////////////////////////////
//find back number
FindBackNumber(7);
return 0;
}
上面的代碼在vs2008調試通過。這個演算法應該還有最佳化的空間,可惜我沒有找到,有高手找了還望不吝賜教:)