定義一個正整數n的函數F(n)為n的每位數的乘積。一個數是good如果F(n)不為0并且n能整除F(n),一個數是完美數當且僅當n是good并且n+1也是good。現在問一個長度是k位的數中有多少個完美數,其中k不大于1000000。
不得不承認這是一個非常經典的鍛煉分析問題能力的題目。設n = a1a2...an,因為F(n)不為0,所以n + 1 = a1a2...(an+1)。根據題目意思,我們可以列出等式:n + 1 = q * (a1 * a2 * ... * (an + 1)),又n = p * (a1 * a2 * ... * an)。令A = a1 * a2 ... * an-1,整理前面的等式可以得到:(q * an + q - an) * A = 1。因為這里面都是整數,顯然A = 1,也就是說a1,a2,...,an-1都是1。問題一下子就變得簡化了很多,比起之前的單純枚舉可以說是進了一大步。但是如果枚舉最后一位判斷是不是可行復雜度依然很高,需要進一步討論。首先an是1、2、5對應的數都是good;an為3的時候,如果是good必須前面n-1個1加和是3的倍數;an為4的時候需要最后兩位被4整除才行,14不滿足條件;同理an為6的時候也必須前面n-1個1加和是3的倍數;an為8的時候需要后三位的數被8整除,顯然也不可能;經過一番討論,就剩7這個特別的數字了。用一堆1對7試除一下發現一個規律,111111恰好整除7,六個數一循環。這樣只需判斷(an - 1)是否整除6就可以了。
綜上所述,對于一個k位的數字,如果k為1,那么結果是8。如果k大于1,結果首先是1,如果k-1能被3整除,結果加2;如果k-1能被6整除,結果再加1。這樣O(1)的時間復雜度就出結果了,仔細分析問題后得出的做法真強大啊。
posted on 2009-06-04 19:57
sdfond 閱讀(372)
評論(0) 編輯 收藏 引用 所屬分類:
Algorithm - Number Theory