첫 풀이 때 메모리 제한
이 있다는 걸 알았지만 3x3 배열
의 상태를 큐로 넣어서 넘기려고 했고 당연히 메모리 초과
가 발생했다.
메모리 초과를 피하기 위해선 리스트
로 위치를 표현하는 방법 대신 문자열
로 위치 상태를 표현해야 한다.
문자열
을 통한 위치 상태 기록 및 방문 파악from collections import deque
def BFS(sx, sy, ch):
q = deque()
q.append((sx, sy, ch, 0))
while q:
tx, ty, ch, count = q.popleft()
if "123456789" == ch:
return count
for dx, dy in (-1, 0), (1, 0), (0, -1), (0, 1):
nx, ny = tx + dx, ty + dy
if 0 <= nx < 3 and 0 <= ny < 3:
a = list(ch)
tmp = a[tx*3 + ty]
a[tx*3 + ty] = a[nx*3 + ny]
a[nx*3 + ny] = tmp
c = ''.join(a)
if not dict_check.get(c):
dict_check[c] = 1
q.append((nx, ny, c, count+1))
return -1
arr = [input().split() for _ in range(3)]
check = []
start_x, start_y = 0, 0
dict_check = dict()
for i in range(3):
for j in range(3):
if arr[i][j] == '0':
arr[i][j] = '9'
start_x = i
start_y = j
check.append(arr[i][j])
check = ''.join(check)
dict_check[check] = 1
print(BFS(start_x, start_y, check))
큐
에 오직 현재 위치 상태를 표시하는 숫자만 넣는다.
다음 시작 위치는 find('9')
를 통해 찾는다.
또한, 방문여부 체크와 이동 횟수를 동시에 기록한다.
...
k = s.find('9') # 9의 index 탐색
x, y = k // 3, k % 3
for dx, dy in (-1, 0), (1, 0), (0, -1), (0, 1): # 0~3
nx, ny = x+dx, y+dy
if nx < 0 or nx >= 3 or ny < 0 or ny >= 3:
continue
nk = nx*3 + ny # 바꿀 위치
ns = list(s)
ns[k], ns[nk] = ns[nk], ns[k] # 리스트를 통한 swap 식
nd = int(''.join(ns)) # 다시 문자열로..
if not dist.get(nd): # 방문 여부 확인
dist[nd] = dist[d] + 1 # 이전 위치에서 + 1
q.append(nd)
...
rebas님 블로그