一個有關神之數字的小題

 有這樣一個題目:
算法

  • 12 + 92 = 82數組

  • 82 + 22 = 68函數

  • 62 + 82 = 100測試

  • 12 + 02 + 02 = 1優化

  • 咱們看到數字 19 通過上面的過程後結果爲1,咱們定義全部經歷上述過程後結果爲1的數字爲「神之數字」,毫無疑問,19就是一個神之數字,如今請你設計一個程序,輸入一個數字,判斷它是不是「神之數字」。spa

  •       毫無疑問,有一手好代碼功夫的人看到如上題目,恐怕都會嗤之以鼻,這算什麼?看老夫給你解決它!然而當本小白看了兩遍題目後仍是一頭霧水,這是要幹什麼?個人老老老老老師祖告訴過咱們,要想多快好省地建設程序代碼,如今就敲 鍵盤,但若是想好省多快地建設程序代碼,如今應該拿筆在紙上寫需求,雖然很囉嗦,我寫需求。設計

  •       給定一個數字,將它的每一位都平方,而後加在一塊兒,直至最後等於1,就是神數。遞歸

  •      需求分析完畢,咱們設計算法,咱們不妨想象一下,咱們能夠用遞歸或循環的方法,不斷地解離一個數字,而後求平方和,假如平方和等於1,皆大歡喜,它就是神數,然而,若是它一直不等於1呢?咱們又怎麼斷定它下一秒、甚至下一萬秒也不會等於1呢?假如不能,豈不是要讓它一直循環下去?數學

  •      這種可怕的狀況固然不會出現,由於咱們堅信宇宙是簡單而又和諧的,不會出現這種狀況(好盲目的信仰)。因此咱們相信,這其中必定會有相應的數學規律,這也是我今天想說的:it

  • 1.萬物皆有其規律所在

  •    咱們對一個數字進行解離,假如是15,第一次過程後結果爲26,第二次過程後結果爲40,第三次過程後結果爲16,第四次過程後結果爲37,第五次過程後結果爲58,第六次爲89,第七次爲145,第八次爲42,第九次爲20,第十次爲4,第十一次爲16!

  •     這時,咱們發現第十一次的結果與第三次的結果是同樣的!假如再進行下去,也不過就是在第三次和第十一次之間徘徊而已,永遠不會出現結果1,那麼15就不會是神數,由於神數經歷最終爲1,再經歷過程仍是爲1,咱們再度隨機抽出幾個數進行上述驗證,結果皆爲如此,這時,咱們能夠肯定,假如一個數在經歷過程當中出現了重複結果,那它就不是神數,知道了這樣的數學規律,咱們能夠給出以下的代碼:

  •    

  • int calcudouble(int n)//一次經歷過程函數

  • {

  • int t = 0;

  • int m = 0;

  • do{

  • m = n%10;

  • n = n/10;

  • t = t+m*m; 

  • }while((m != 0) || (n != 0));

  • return t;

  • }

  • int check_godnumber(int n) //判斷神數的函數

  • {

  •         int arrayli[10000] = {0};

  • int currentreu = calcudouble(n);

  • arrayli[currentreu] = 1;

  • while(1 != currentreu)

  • {

  • currentreu = calcudouble(currentreu);

  • if(arrayli[currentreu] == 0)

  • {

  • arrayli[currentreu] = 1;

  • }

  • else

  • {

  • break;

  • }

  • }

  • if(currentreu == 1)

  • {

  • return 1;

  •         }

  • else

  • {

  • return 0;

  • }

  •  }

  • 總體的思想是:創建一個數組,數組的全部項所有初始化爲0,輸入一個數字,一次過程後結果爲N,假如N不爲1,則數組【N】賦值爲1,以後每一次結果都重複如此,在賦值的同時,檢查數組【N】是否早就爲1,已經爲1,代表出現了重複,此數不是神數!

  • 真是皆大歡喜,若是咱們只是碼農,咱們就能夠收工了,可是我是要成爲碼農王的男人!因此,咱們仍是看看是否有優化的餘地吧。。。。

  • 咱們發現,申請了一個1000的數組,然而在經歷過程當中咱們只不過使用了其中的某幾項,其餘的大多數項根本沒有用到,這好像有點浪費空間,而咱們是不斷過程到出現重複過程才能進行判斷,這在時間上好像也有浪費,無數碼農的經驗告訴咱們既浪費時間又浪費空間的算法每每不是好的算法,那麼,是否還有更好的方法呢?

  • 2.尋找更簡單的規律

  • 上次咱們測試了15,發現它不是神數,咱們繼續測試一些數字,發現了另外一條規律(有興趣的能夠本身發掘發掘,再也不多寫過程了):每個數的過程路徑上一定會出現一個小於10的個位數,而咱們測試了全部的個位數,假如不是1和7,就會出現重複,也就不是神數!

  • 原來如此,根據這個規律,我給出以下代碼:

  • int check_gounumber(int n)

  • {

  • int currentreu = calcudouble(n);

  • while(1 != currentreu)

  • {

  • currentreu = calcudouble(currentreu);

  • if(currentreu < 10)

  • {

  • if(currentreu == 1)

  • {

  • return 1;

  • }

  • else

  • {

  • return 0;

  • }

  • }

  • }

  • return 0;

  • }

  • 相比以前的算法,該算法既節省了空間,又節省了時間,更加地天然而又簡潔,讓人喜悅。

  • 通過此次作題,我得出新的體會:在解決問題以前,先找準問題相關的規律,可以更加地事半功倍,而找到更好更簡單的規律,則是邁向進步的開端。

相關文章
相關標籤/搜索