[๋ฐฑ์ค 1525 ๐ฅ] ํผ์ฆ
๋ฌธ์
3×3 ํ์ ๋ค์๊ณผ ๊ฐ์ด ์๊ฐ ์ฑ์์ ธ ์๋ค. ์ค๋ฅธ์ชฝ ์๋ ๊ฐ์ฅ ๋ ์นธ์ ๋น์ด ์๋ ์นธ์ด๋ค.
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 |
์ด๋ค ์์ ์ธ์ ํด ์๋ ๋ค ๊ฐ์ ์นธ ์ค์ ํ๋๊ฐ ๋น์ด ์์ผ๋ฉด, ์๋ฅผ ๊ทธ ์นธ์ผ๋ก ์ด๋์ํฌ ์๊ฐ ์๋ค. ๋ฌผ๋ก ํ ๋ฐ๊นฅ์ผ๋ก ๋๊ฐ๋ ๊ฒฝ์ฐ๋ ๋ถ๊ฐ๋ฅํ๋ค. ์ฐ๋ฆฌ์ ๋ชฉํ๋ ์ด๊ธฐ ์ํ๊ฐ ์ฃผ์ด์ก์ ๋, ์ต์์ ์ด๋์ผ๋ก ์์ ๊ฐ์ ์ ๋ฆฌ๋ ์ํ๋ฅผ ๋ง๋๋ ๊ฒ์ด๋ค. ๋ค์์ ์๋ฅผ ๋ณด์.
1 | 3 | |
4 | 2 | 5 |
7 | 8 | 6 |
1 | 2 | 3 |
4 | 5 | |
7 | 8 | 6 |
1 | 2 | 3 |
4 | 5 | |
7 | 8 | 6 |
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 |
๊ฐ์ฅ ์ ์ํ์์ ์ธ ๋ฒ์ ์ด๋์ ํตํด ์ ๋ฆฌ๋ ์ํ๋ฅผ ๋ง๋ค ์ ์๋ค. ์ด์ ๊ฐ์ด ์ต์ ์ด๋ ํ์๋ฅผ ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์์ค.
์ ๋ ฅ
์ธ ์ค์ ๊ฑธ์ณ์ ํ์ ์ฑ์์ ธ ์๋ ์ํ ๊ฐ์ ์๊ฐ ์ฃผ์ด์ง๋ค. ํ ์ค์ ์ธ ๊ฐ์ ์๊ฐ ์ฃผ์ด์ง๋ฉฐ, ๋น ์นธ์ 0์ผ๋ก ๋ํ๋ธ๋ค.
์ถ๋ ฅ
์ฒซ์งธ ์ค์ ์ต์์ ์ด๋ ํ์๋ฅผ ์ถ๋ ฅํ๋ค. ์ด๋์ด ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ -1์ ์ถ๋ ฅํ๋ค.
๋ฌธ์ ํ์ด
import sys
from collections import deque
target=[['1','2','3'],['4','5','6'],['7','8','0']]
numbers=[list(sys.stdin.readline().strip().split(' ')) for _ in range(3)]
ans=1e9
# DFS๋ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ํ์ํด์ผ ํด์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๋ณด์ฅํ๋ BFS๋ก ํ์ด์ผ ํจ.
# def dfs(blank,count):
# global ans, numbers
# if numbers==target:
# ans=min(ans, count)
# return
# for di in directions:
# by=blank[0]+di[0]
# bx=blank[1]+di[1]
# if 0<=by<3 and 0<=bx<3:
# numbers[blank[0]][blank[1]]=numbers[by][bx]
# numbers[by][bx]=0
# dfs((by,bx),count+1)
# numbers[by][bx]=numbers[blank[0]][blank[1]]
# numbers[blank[0]][blank[1]]=0
visited=set()
def bfs(blank, count, numbers):
global ans
queue=deque()
queue.append((blank[0], blank[1], count, numbers))
directions = [(0, 1), (1, 0), (-1, 0), (0, -1)]
while queue:
blank_y,blank_x,c,num=queue.popleft()
if num==target:
ans=c
return
for di in directions:
by=blank_y+di[0]
bx=blank_x+di[1]
if 0<=by<3 and 0<=bx<3:
new_numbers = [arr[:] for arr in num]
new_numbers[blank_y][blank_x] = new_numbers[by][bx]
new_numbers[by][bx]='0'
str_new_number=''.join(sum(new_numbers,[]))
if str_new_number not in visited:
queue.append((by,bx,c+1, new_numbers))
visited.add(str_new_number)
for i in range(3):
for j in range(3):
if numbers[i][j]=='0':
visited.add(''.join(sum(numbers,[])))
bfs((i,j),0, numbers)
if ans!=1e9:
print(ans)
else:
print(-1)
sys.exit(0)
- ์ฒ์์ DFS๋ฅผ ์ด์ฉํด์ ์์ง์ด๋ ์ขํ๋ณ๋ก visited ๋ฐฐ์ด์ ๋งค ํ๋ง๋ค ๋ฃ์ด์ค ํ์์์ด visited๋ฅผ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌํด์คฌ๋ค๊ฐ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํด์ ํด์คฌ๋ค๊ฐ ํ๋ฉด์ DFS ํ์์ ์ด์ฉํด์ ๊ตฌํ ์ ์์ ๊ฒ์ด๋ผ ์๊ฐํด์ DFS๋ก ํ์๋๋ ์๊ฐ ์ด๊ณผ๊ฐ ๋ฐ์ํ๋ค.
- numbers ๋ฐฐ์ด๊ณผ target ๋ฐฐ์ด์ด ์ผ์นํ๋๋ผ๋ ์ต์๊ฐ ๋ณด์ฅ๋์ง ์๋ DFS ํน์ฑ์ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ํ์ํ๊ณ ๊ทธ ์ค ๊ฐ์ฅ ์์ count ๊ฐ์ ๊ตฌํด์ผํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ์์ DFS๋ฅผ ์ฌ์ฉํ๊ธฐ์ ๋ฌด๋ฆฌ๊ฐ ์๋ค.
- ๊ทธ๋์ BFS๋ก ๋ณ๊ฒฝํด์ ํ์๋ค! ๋์ ๊ฐ ๊ฒฝ๋ก๋ง๋ค ์๋ก์ด visited ๋ฐฐ์ด์ ํ์ ๋ฃ์ด์ฃผ๋ฉด์ ํ์ด์ผ ํ๋ค. ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ ํฌ๋ค๋ฉด ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ด๊ณผ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์์ง๋ง, ์ด ๋ฌธ์ ์ ๊ฒฝ์ฐ 3x3 ๋ฐฐ์ด๋ก ๊ณ ์ ๋์ด ์๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํ๋ค.
- ๊ทธ๋ฆฌ๊ณ BFS๋ฅผ ๋๋ฉด์ ๋ฐฉ๋ฌธํ๋ ํ ์ํ์ธ์ง ํ์ธํ๊ณ , ๋ฐฉ๋ฌธํ ๊ฒฝ์ฐ์ด๋ฉด ํ์ ๋ฃ์ด์ฃผ์ง ์์์ผ ํ๋ค. ์ด ๋ถ๋ถ์์ ํด๋น ํ ์ํ๋ฅผ ์ง๋๊ฐ์๋์ง๋ set๊ณผ ๋ฌธ์์ด์ ์ด์ฉํด์ ๊ตฌํํ๋ค.
- set์ in ์ฐ์ฐ์๊ฐ ์์ ์๊ฐ์ด๋ฏ๋ก visited set ์์ ๋ฐฉ๋ฌธํ๋ค๊ณ ์ ์ฅ๋ ๋ฌธ์์ด์ธ์ง ํ์ธํ๊ธฐ์ ์ฉ์ดํ๋ค.
- numbers=[['1','0','3'],['2','5','6'],['4','7','8']]์ด๋ผ๋ ํ ์ํ๊ฐ ์๋ค๋ฉด sum(numbers, [])๋ฅผ ํ๋ฉด ['1','0','3','2','5','6','4','7','8']๋ก ๋ณ๊ฒฝ์ด ๋๋ค. ์ด๋ ๊ฒ ๋ณ๊ฒฝ๋ ๋ฐฐ์ด์ ''.join(sum(numbers, []))์ผ๋ก '103256478'๋ก ๋ณ๊ฒฝ์ด ๋๊ณ , ์ด๋ฅผ visited set์ ๋ฃ์ด์ค์ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํด์ค๋ค.
- ์ด๋ฌํ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ง ์์ผ๋ฉด target ๋ฐฐ์ด์ธ [[1,2,3],[4,5,6],[7,8,0]]์ ๊ตฌํ๋ฉด return๋๋ BFS์ while ์ข ๋ฃ ์กฐ๊ฑด์ ๊ตฌํ ์๊ฐ ์์ด์ ๋ฌดํ ๋ฃจํ๋ฅผ ๋๊ฒ ๋๋ฏ๋ก ๊ผญ! ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํด์ค์ผ ํ๋ค.