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
๋๋ ¶
- ์ง์์ ์ผ๋ก ํผํฌ๋จผ์ค ํ๋์ ์ํด ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์ ๊ทผ์ ํด๋ณธ ์ ์ด ์ข์์.
- ํ์ง๋ง, ์ํ์ ์ธ ๊ด๊ณ๋ฅผ ์ฐพ์๋ด๋๋ฐ์๋ ์ญ์ ํ๊ณ๋ฅผ ๋ณด์. ๊ทธ๋ฅ ํผํฌ๋จผ์ค ํฅ์์ ์ํ ์๊ณ ๋ฆฌ์ฆ ๊ฐ์ ๋ฒ์ผ๋ก๋ง ์ ๊ทผ.
๋๋ฌด ์ง๊ด์๋ง ์์กดํ์ฌ ํผ ์ ์ด ์์ฝ๊ธด ํจ.
- ๋ค์๊ธ '์ด ๋ฌธ์ ์์ ์๊ตฌํ ๋ฐฉ๋ฒ์ด ์ด ๋ฐฉ๋ฒ์ด์์๊น?' ์ ๋ํด์ ๊ณ ๋ฏผํ๊ฒ ๋จ. ๋น๋ก ์ํ๋ ์ฑ๋ฅ์ ๋์ค๊ธด ํ์ง๋ง.










