approach ¶
1μ°¨ μλ ¶
λλ΅ μ°μ΅μ₯μ μμ΄μ΄ λ§λ€μ΄μ§ λͺ¨μ΅μ μκ°νλ©΄μ λμμΈ, 20λΆ μ λ μ½λ©.
~cpp def selfDescrib(n): table = [1,2,2] e=2 while e!=n+1: e+=1 table += [e] * table[e-1] if len(table) > n-1: return table[n-1] for i in [100,9999,123456,1000000000]: print selfDescrib(i)
2μ°¨ μλ ¶
λ¬Έμ λ, 1000000000 μ κ²½μ°μ λν΄μ λ΅μ΄ λμ€λ μκ°μ΄ μμ²λκ² κ±Έλ¦°λ€λ μ μ΄λ€. μ΄μ λν΄μ μ΄λ»κ² ν κ²μΈκ° κ³ λ―Ό,
μ¬λ¬ μ κ·Όλ²μ λν΄μ μκ°νκ² λ¨.
μ¬λ¬ μ κ·Όλ²μ λν΄μ μκ°νκ² λ¨.
- μμ΄μ λν μΌλ°μμ΄ μμκΉ?
- k κ° λλΉ f(k) κ°μ ν¨μ¬λ λ§μ΄ μμλΌ μ μμν
λ°, μ΄λ₯Ό μ΄μ©ν λ°©λ²μ΄ μμκΉ?
3μ°¨ μλ ¶
μ΄μ μ μ΄μ΄μ κ³ λ―Όνλ μ€, λ¬Έμ μ μ λν΄μ λ€μ μκ°. κ²°κ΅μ f(k) λ₯Ό μν table μμ±μμ λ©λͺ¨λ¦¬λ₯Ό λ§μ΄ μ΄λ€λ μ μ΄ λ¬Έμ .
μ΄μ λν΄μ λ€λ₯΄κ² representation ν λ°©λ²μ μκ°νλ€κ° λ€μκ³Ό κ°μ΄ representation ν λ°©λ²μ λ μ¬λ¦¬κ² λ¨.
μ΄μ λν΄μ λ€μκ³Ό κ°μ΄ ꡬν
νκ³ λλ, κ·Έλλ μμ 1000000000 μ λν΄μλ κ΅μ₯ν λλ¦Ό. λ릴 λΆλΆμ μκ°νλ μ€ findGroupIdx λΆλΆμ΄
λ¬Έμ μμ μκ°. μ΄λ₯Ό binary search ꡬνμΌλ‘ λ°κΏ.
binary search λ‘ λ°κΎΈκ³ λμλ μμ μ€λκ±Έλ¦Ό. λ€λ₯Έ κ²μλ²μ λν΄μ μκ°νλ μ€, findGroupIdx ν¨μ νΈμΆμ ν λλ₯Ό μκ°.
μμ΄μ κ°μ΄ λ μ¦κ°νλ€ ν λ λ€μλ²μ κ²μνλ κ²½μ° μμμ κ²μνλ κ·Έλ£Ή μλλ©΄ κ·Έ λ€μ κ·Έλ£Ήμμ μκ°νκ² λ¨.
μν μκ° : 1000000000 κΈ°μ€ 0.95μ΄(with psyco) 2.18μ΄(without psyco)
λ©λͺ¨λ¦¬ μ¬μ©λ : 31MB
μ΄μ λν΄μ λ€λ₯΄κ² representation ν λ°©λ²μ μκ°νλ€κ° λ€μκ³Ό κ°μ΄ representation ν λ°©λ²μ λ μ¬λ¦¬κ² λ¨.
f(1) : 1 f(2) ~ f(3) : 2 f(4) ~ f(5) : 3 f(6) ~ f(8) : 4 f(9) ~ f(11) : 5 . .
~cpp # ν΄λΉ μ«μ λ²μλ₯Ό μ‘°μ¬νμ¬ μ΄λ€ κ°μ΄ λμ¬μ§λ₯Ό return def findGroupIdx(table,n,startPos=0): for i in xrange(len(table)): x,y=table[i] if x<=n<=y: return i+1 def selfDescrib2(n): table=[(1,1),(2,3)] if n==1 or n==2: return n for i in xrange(3,n+1): start = table[-1][-1] + 1 theGroupIdx = findGroupIdx(table,i) repeat = theGroupIdx end = start + repeat - 1 table.append((start,end)) if start >= n: return findGroupIdx(table,n)
λ¬Έμ μμ μκ°. μ΄λ₯Ό binary search ꡬνμΌλ‘ λ°κΏ.
~cpp def findGroupIdx(table,n,startPos=0): midIdx = len(table)/2 mid = table[midIdx] x,y=mid if x<=n<=y: return midIdx+1+startPos if n<x: return findGroupIdx(table[:midIdx],n,startPos) else: return findGroupIdx(table[midIdx+1:],n,startPos+midIdx+1)
μμ΄μ κ°μ΄ λ μ¦κ°νλ€ ν λ λ€μλ²μ κ²μνλ κ²½μ° μμμ κ²μνλ κ·Έλ£Ή μλλ©΄ κ·Έ λ€μ κ·Έλ£Ήμμ μκ°νκ² λ¨.
~cpp class FindGroupIdxs: def __init__(self,table): self._table = table self._prevSearchPos = 0 def find(self,n): while True: x,y=self._table[self._prevSearchPos] if x<=n<=y: return self._prevSearchPos+1 self._prevSearchPos+=1 def selfDescrib2(n): table=[(1,1),(2,3)] if n==1 or n==2: return n finder = FindGroupIdxs(table) for i in xrange(3,n+1): start = table[-1][-1] + 1 theGroupIdx = finder.find(i) repeat = theGroupIdx end = start + repeat - 1 table.append((start,end)) if start >= n: return finder.find(n) def main(): import time for e in [100,9999,123456,1000000000]: start=time.time() print e,selfDescrib2(e) print "time : ", time.time()-start import psyco psyco.full() main()
λ©λͺ¨λ¦¬ μ¬μ©λ : 31MB
λλ ¶
- μ§μμ μΌλ‘ νΌν¬λ¨Όμ€ νλμ μν΄ λ€λ₯Έ μκ³ λ¦¬μ¦μΌλ‘ μ κ·Όμ ν΄λ³Έ μ μ΄ μ’μμ.
- νμ§λ§, μνμ μΈ κ΄κ³λ₯Ό μ°Ύμλ΄λλ°μλ μμ νκ³λ₯Ό 보μ. κ·Έλ₯ νΌν¬λ¨Όμ€ ν₯μμ μν μκ³ λ¦¬μ¦ κ°μ λ²μΌλ‘λ§ μ κ·Ό.
λ무 μ§κ΄μλ§ μμ‘΄νμ¬ νΌ μ μ΄ μμ½κΈ΄ ν¨.
- λ€μκΈ 'μ΄ λ¬Έμ μμ μꡬν λ°©λ²μ΄ μ΄ λ°©λ²μ΄μμκΉ?' μ λν΄μ κ³ λ―Όνκ² λ¨. λΉλ‘ μνλ μ±λ₯μ λμ€κΈ΄ νμ§λ§.