定义一个正整数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 阅读(364)
评论(0) 编辑 收藏 引用 所属分类:
Algorithm - Number Theory