1. 程式人生 > >483. Smallest Good Base

483. Smallest Good Base

解法

參考:https://blog.csdn.net/qq_23997101/article/details/73135615

數學推理題…………………………………………
本質是找a和k,使得: n = 1 + a +

a 2 + . . . + a k
( k > = 1 ) n=1+a+a^2+...+a^k (k>=1)
所以有: n > a k n k > a n>a^k\Rightarrow \sqrt[k]{n}> a
又知 ( 1 + a ) k = 1 + C k 1 a + C k 2 a 2 + . . . + C k k a k n (1+a)^k = 1+C_k^1a+C_k^2a^2+...+C_k^ka^k\ge n
即有: a n k 1 a\ge\sqrt[k]{n}-1
綜上,如果a進位制化後長為k+1,那麼 n k > a n k 1 \sqrt[k]{n}>a \ge \sqrt[k]{n}-1 ,就是:

  • n k \sqrt[k]{n} 為整數時, a = n k 1 a=\sqrt[k]{n}-1
  • n k \sqrt[k]{n} 為非整數時, a = n k a=\lfloor\sqrt[k]{n}\rfloor

當k越大的時候a越小,k最大有多大呢?
a t a\ge t 時,k最大為 a = t a=t 的時候,長度為 l o g t ( n + 1 ) 1 \lceil log_t(n+1)\rceil-1

所以我們現在得到了2條結論:

  1. k確定時,a怎麼選:
  • n k \sqrt[k]{n} 為整數時, a = n k 1 a=\sqrt[k]{n}-1
  • n k \sqrt[k]{n} 為非整數時, a = n k a=\lfloor\sqrt[k]{n}\rfloor
  1. t確定時,應該從哪裡開始搜: l o g t ( n ( t 1 ) + 1 ) 1 \lceil log_t(n(t-1)+1)-1\rceil

所以演算法如下:

  1. 初始時,t=2,算出一個長度k,再根據k算出一個a(當然這時a明顯為2)。
  2. 如果a滿足條件,那麼顯然它是最小的,返回
  3. 如果a不滿足條件,那下一個k在哪呢?下一個k至少要比當前的k小,並且下一個k算出來的a要大於現在的a,所以有: k = m i n ( k 1 , l o g t + 1 ( n t + 1 ) 1 ) k = min(k-1, \lceil log_{t+1}(nt+1)-1\rceil)

有一個坑是k=1的時候算base,明顯base=n-1,但是轉成浮點再轉回整數可能有問題,所以如果最後也沒返回結果,預設返回保底的n-1

程式碼:

class Solution(object):
    def smallestGoodBase(self, n):
        """
        :type n: str
        :rtype: str
        """
        n = long(n)
        import math
        def good_base(n,k):
            tmp = math.pow(n,1.0/k)
            if abs(long(tmp)-tmp)<10**-6:
                return long(tmp)-1
            else:
                return long(tmp)

        def is_good_base(n,k):
            if n%k!=1:
                return False
            if n==1:
                return True
            return is_good_base((n-1)/k,k)
        now = int(math.ceil(math.log(n+1, 2)-1))
        while now>=1:
            base = good_base(n,now)
            if is_good_base(n,base):
                return str(base)
            now = min(int(math.ceil(math.log(n*base+1, base+1)-1)), now-1)
        return str(n-1)