intro
๐ผ ์ ๋ช ํ 'ํ๋ ธ์ด์ ํ' ์๊ณ ๋ฆฌ์ฆ์ ๋ํด ์๊ฐํ๋ค. 3๊ฐ์ ๊ธฐ๋ฅ์ด ์๊ณ , ๋ค์ํ ํฌ๊ธฐ์ n๊ฐ์ ์ํ(์ํ์ ํฌ๊ธฐ๋ ๋ชจ๋ ๋ค๋ฅด๋ค)์ด ์กด์ฌํ๋ค. ํผ์ฆ์ ์์ํ๊ธฐ ์ ์๋ ํ ๊ธฐ๋ฅ์ n๊ฐ์ ์ํ๋ค์ด ์์ ๊ฒ์ด ์์ ์๋๋ก ์์๋๋ก ์์ฌ ์๋ค. ์๋ 3๊ฐ์ง ์กฐ๊ฑด์ ๋ง์กฑ ์ํค๋ฉด์ ๋ค๋ฅธ ๊ธฐ๋ฅ์ผ๋ก ์ฎ๊ฒจ์ ๋ค์ ์๋ ํผ์ฆ์ด๋ค.
โ ํ ๋ฒ์ 1๊ฐ์ ์ํ๋ง ์ฎ๊ธธ ์ ์๋ค.
โก ๊ฐ์ฅ ์์ ์๋ ์ํ๋ง ์ด๋ํ ์ ์๋ค.
โข ํฐ ์ํ์ด ์์ ์ํ ์์ ์์ด์๋ ์๋๋ค.
์ด ๋, ์ต์ ์ด๋ํ์๋ก ๋งจ ์ผ์ชฝ ๊ธฐ๋ฅ์์ ๋งจ ์ค๋ฅธ์ชฝ ๊ธฐ๋ฅ์ผ๋ก n๊ฐ์ ์ํ์ ์์์ ๋ง์ถ์ด์ ์์์ฃผ๋ฉด ๋๋ค
example demo (n=3)
๐ผ n=3์ผ ๋ Hanoi Tower๋ฅผ ์์๋ณด์!
๐ผ Hanoi Tower ๋ฌธ์ ๋ ํฌ๊ฒ ์๋ 3๊ฐ์ง ์์๋ก ์งํ๋๋ค.
* Hanoi(3,A,C,B): 3๊ฐ์ ์๋ฐ์ A์์ C๊น์ง (B๋ฅผ ๊ฑฐ์ณ) ์ฎ๊ธฐ๋ ๊ณผ์
โ 1๋ฒ๋ถํฐ 4๋ฒ๊น์ง์ ๊ณผ์ = Hanoi(2,A,B,C)
: ๋จผ์ ๋งจ ์๋ N๋ฒ์ ์๋ฐ์ ์ ์ธํ๊ณ (N-1)๊ฐ์ ์๋ฐ์ A์์ ๋ฐ๋ก ์ B๋ก ์ฎ๊ธด๋ค
โก 5๋ฒ ๊ณผ์
: A์ ์๋ N๋ฒ ์๋ฐ์ C๋ก ์ฎ๊ธด๋ค
โข 6๋ฒ๋ถํฐ 8๋ฒ๊น์ง์ ๊ณผ์ = Hanoi(2,B,C,A)
: B์ ์๋ (N-1)๊ฐ์ ์๋ฐ์ C๋ก ์ฎ๊ธด๋ค
* ์ 3๊ฐ์ง ๊ณผ์ ์ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ด๋ฉด ์๋์ ๊ฐ๋ค.
recursion & code
๐ผ ๋ฐ๋ผ์ Hanoi(3,A,C,B)๋ ์๋์ ๊ฐ์ด ๋ํ๋ผ ์ ์๋ค.
(์ด ๋, move(N,1,3)์ N๋ฒ ์๋ฐ์ 1๋ฒ์์ 3๋ฒ ๊ธฐ๋ฅ์ผ๋ก ์ฎ๊ธฐ๋ ๊ฒ์ ๋ปํจ)
Hanoi(3,A,C,B) = Hanoi(2,A,B,C) + Hanoi(1,A,C,B) + Hanoi(2,B,C,A)
๐ผ ์ผ๋ฐํํ๋ค๋ฉด
Hanoi(N,A,C,B) = Hanoi(N-1,A,B,C) + Hanoi(1,A,C,B) + Hanoi(N-1,B,C,A)
โ Hanoi(N,start,dest,via) = Hanoi(N-1,start,via,dest) + Hanoi(1,start,dest,via) + Hanoi(N-1,via,dest,start)
(if N == 1 then move 1 plate to dest and return)
: "Hanoi(N,A,C,B) = N-1๊ฐ์ ์๋ฐ์ ๋จผ์ A์์ B๋ก ์ฎ๊ธฐ๊ณ , ๋จ์ N๋ฒ์งธ ์๋ฐ์ C๋ก ์ฎ๊ธด ๋ค, B์ ์๋ N-1๊ฐ์ ์๋ฐ์ C๋ก ์ฎ๊ธด๋ค"
๐ผํ์ด์ฌ ์ฝ๋๋ฅผ ์๋์ ๊ฐ์ด ๋ํ๋ผ ์ ์๋ค. 3๊ฐ์ ์๋ฐ์ด ์ฎ๊ธฐ๋ ๊ณผ์ ์ ์ถ๋ ฅ.
ans=[]
def hanoi(n,a,c,b):
if n == 1:
ans.append((a,c))
else:
hanoi(n-1,a,b,c)
hanoi(1,a,c,b)
hanoi(n-1,b,c,a)
hanoi(3,1,3,2)
for x in ans:
print(*x)
'''
1 3
1 2
3 2
1 3
2 1
2 3
1 3
'''
number of moves
๐ผN๊ฐ์ ์๋ฐ์ ํ๋ ธ์ด ํ์์ ์์ง์ด๋ ํ์๋ฅผ hanoi(N)์ด๋ผ ํ์
hanoi(N) = hanoi(N-1) + 1 + hanoi(N-1)
(N==1์ด๋ผ๋ฉด hanoi(1) = 1)
: hanoi(N)์ a_n์ด๋ผ ํ๋ฉด ์๋ ๊ทธ๋ฆผ์ ์ํด hanoi(N) = 2^n - 1
exercises
โ <BOJ G5 11729 ํ๋ ธ์ด ํ ์ด๋ ์์> โ
Q. N๊ฐ์ ์ํ์ ํ๋ ธ์ด ํ ์ด๋ ์์ ์ฐจ๋ก๋๋ก ์ถ๋ ฅ(ํ๋ ธ์ด ํ ์ ์์ ์ฝ๋์ ๋์ผ). ์ด๋ ํ์๋ 2^N-1๋ก ์ถ๋ ฅ
โ <BOJ G5 1914 ํ๋ ธ์ด ํ> โ
Q. ์ 11729 ๋ฌธ์ ์ ๋์ผ
โ <BOJ G4 23250 ํ๋ ธ์ด ํ K> โ
Q. K๋ฒ์งธ ์ด๋์ ์ถ๋ ฅ. ์ด ๋ ์๊ฐ์ด๊ณผ ๋ฐฉ์ง๋ฅผ ์ํด ์ ํ์ ์ผ๋ก ์ฌ๊ท ํ์ฉ. N๊ฐ์ ์ํ์ด๋ผ๋ฉด ์ฒซ hanoi() ํจ์๋ (2^(n-1)-1) ํ์ ์ดํ์ผ ๋๋ง, ๋๋ฒ์งธ ๋จ๋ ์ด๋์ 2^(n-1)๋ฒ์งธ ์ด๋. ๋ ๋ฒ์งธ hanoi() ํจ์๋ 2^(n-1)+1 ~ 2^(n)-1 ๋ฒ์งธ ์ด๋์ผ ๋๋ง, ์ฌ๊ท ๋๋ฆฐ๋ค.
โ <BOJ S2 15500 ์ด์ํ ํ๋ ธ์ด ํ> โ
Q. ๊ธฐ์กด ํ๋ ธ์ด ํ์ ์ํ ์์๋๋ก ๋ง๋์ ์์นํด ์์ด์ผ ํ๋, ์ํ ์์๋๋ก ์์ ํ์ ์๋ ๋ณํ๋ ํ๋ ธ์ด ํ ๋ฌธ์ . ์ต์ ์ด๋ ํ์๋ ๊ทธ์ ๋น์ฅ ๊ฐ์ฅ ๋ฌด๊ฒ๊ฐ ๋ง์ด ๋๊ฐ๋ ์ํ์ ์ฐพ์ ๋๊น์ง ์๋ฎฌ๋ ์ด์ ์ผ๋ก ๋ฐ๊พผ ํ์. pop() + append() ๋ฐ๋ณตํ๊ณ ์ฐพ์ผ๋ฉด pop()ํ ๋ค ์ธ๋ฒ์งธ ์ต์ข ๋ง๋์ append(). stack + simulation์ผ๋ก ๊ทธ์ ํ๋ฆฌ๋ ๋ฌธ์ .
+ printing disk number
๐ผ ์์ ํ์ตํ ํ๋ ธ์ด์ ํ ์ฌ๊ท ์๊ณ ๋ฆฌ์ฆ์์ ์ด๋ํ๋ ๋ง๋์ ์ข ๋ฅ(์ด์ /์ดํ)๋ฅผ ์ถ๋ ฅํ๋ ๊ฒ ์ธ๋ก ๋งจ ์๋ถํฐ ์์ ์์๋๋ก 1๋ฒ, 2๋ฒ, 3๋ฒ ์ด๋ ๊ฒ N๋ฒ๊น์ง ๋ฒํธ๋ฅผ ๋งค๊ฒผ์ ๋, ๋ช ๋ฒ์ ์ํ์ด ์ด๋ํ๋ ์ง disk number๋ ๋์ค์ ํ์ธํ ์ ์๋ค.
โ hanoi ์ฌ๊ท ์ฝ๋๋ฅผ ์ง๊ด์ ์ผ๋ก ๋ณด๋ฉด else๋ฌธ์์์ move๋ N๋ฒ ์ํ์ ์ฎ๊ธฐ๊ณ (2~N๋ฒ) / if๋ฌธ์์์ move๋ ์ฌ๊ท ์ข ๋ฃ ์ฒ๋ฆฌ๋ฅผ ์ํด ๋ง์ง๋ง์ผ๋ก ๋จ์ 1๋ฒ ์ํ์ ์ฎ๊ธฐ๋(1๋ฒ), ๋ ์ข ๋ฅ์ move๋ก ๋ถ์ํ ์ ์๋ค.
โ ๋ฐ๋ผ์ ๋ ์ข ๋ฅ์ move(N๋ฒ ์๋ฐ ์ฎ๊ธฐ๋ move๋ (N,์ถ๋ฐ์ง์ ,๋์ฐฉ์ง์ )์ ans์ append / 1๋ฒ ์๋ฐ ์ฎ๊ธฐ๋ move(์ฌ๊ท ์ข ๋ฃ์ฉ)๋ (1,์ถ๋ฐ์ง์ ,๋์ฐฉ์ง์ )์ ans์ append)
ans=[]
def hanoi(n,a,c,b):
if n == 1:
ans.append((1,a,c))
else:
hanoi(n-1,a,b,c)
ans.append((n,a,c))
hanoi(n-1,b,c,a)
n=int(input())
print(2**n-1)
hanoi(n,1,3,2)
for pair in ans:
n1,n2,n3=pair[0],pair[1],pair[2]
n2='XABC'[n2]
n3='XABC'[n3]
print(f'move disk {n1} {n2}->{n3}')
'Computer Science > Algorithms' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐๏ธEuler Sieve (1) | 2024.04.21 |
---|---|
๐ฅCounting Sort (0) | 2024.04.17 |
โMerge Sort (0) | 2024.04.06 |
๐ก Two Pointers (1) | 2024.02.11 |
๐ฆ Pigeonhole Principle (0) | 2024.02.02 |
๋๊ธ