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
λλ ¶
- μ§μμ μΌλ‘ νΌν¬λ¨Όμ€ νλμ μν΄ λ€λ₯Έ μκ³ λ¦¬μ¦μΌλ‘ μ κ·Όμ ν΄λ³Έ μ μ΄ μ’μμ.
- νμ§λ§, μνμ μΈ κ΄κ³λ₯Ό μ°Ύμλ΄λλ°μλ μμ νκ³λ₯Ό 보μ. κ·Έλ₯ νΌν¬λ¨Όμ€ ν₯μμ μν μκ³ λ¦¬μ¦ κ°μ λ²μΌλ‘λ§ μ κ·Ό.
λ무 μ§κ΄μλ§ μμ‘΄νμ¬ νΌ μ μ΄ μμ½κΈ΄ ν¨.
- λ€μκΈ 'μ΄ λ¬Έμ μμ μꡬν λ°©λ²μ΄ μ΄ λ°©λ²μ΄μμκΉ?' μ λν΄μ κ³ λ―Όνκ² λ¨. λΉλ‘ μνλ μ±λ₯μ λμ€κΈ΄ νμ§λ§.










