[파이썬] 백준 1473 : 미로 탈출 (플레5)
풀이
방향성 생각
- 작은 맵 + state가 변하는 2 요소 = 비트필드를 이용한 BFS
- 카카오 기출에서 비슷한 문제가 있었다.
- 현재 맵 상태를 bit로 나타내고 큐에 같이 넣어주기.
- 가로로 이동하는 경우
- 현재 칸이 가로로 이동가능 (A or 회전안된D or 회전된 C)
- 다음 칸이 가로로 이동가능 (A or 회전안된D or 회전된 C)
- 다음 칸이 가로로 이동 불가능 (회전된D or 회전안된C)
- 세로로 이동하는 경우도 마찬가지이다.
- 현재에서 원하는 방향으로 나갈 수 있는지 체크
- 다음 칸이 회전 안하고 갈 수 있는지 체크 (상태 s 그대로)
- 다음 칸을 회전하고 가야 하는지 체크 (상태 ns로 변경 후 제자리에 큐 추가)
전체코드
from collections import deque, defaultdict as dd
inside = lambda x,y : 0<=x<W and 0<=y<H
dire = [(1,0),(0,1),(-1,0),(0,-1)]
def toggle(x,y,s):
ns = s
for j in range(y*W,y*W+W): # 행 토글
ns ^= (1<<j)
for i in range(x,W*H,W): # 열 토글
ns ^= (1<<i)
return ns
def update(x,y,s,t):
global V,G
if V[(x,y,s)] == -1:
V[(x,y,s)] = t+1
Q.append((x,y,s,t+1))
H,W = map(int,input().split())
arr = [input() for _ in range(H)]
V = dd(lambda : -1)
V[(0,0,0)] = 0 # x y s -> t
Q = deque([(0,0,0,0)])
answer = -1
while Q:
x,y,s,t = Q.popleft()
if (x,y) == (W-1,H-1):
answer = t
break
for idx,(dx,dy) in enumerate(dire):
nx,ny = x+dx,y+dy
is_ver = idx%2
ns = toggle(x,y,s)
if inside(nx,ny) and arr[ny][nx] != 'B':
# 세로이동
if is_ver and (arr[y][x] == 'A' or (arr[y][x] == 'C' and not s&(1<<(x+y*W))) or (arr[y][x] == 'D' and s&(1<<(x+y*W)))):
# 제자리에서 회전
update(x,y,ns,t)
# 회전 x : 다음 A or 회전안된 C or 회전된 D
if (arr[ny][nx] == 'A') or (arr[ny][nx] == 'C' and not s&(1<<(nx+ny*W))) or (arr[ny][nx] == 'D' and s&(1<<(nx+ny*W))):
update(nx,ny,s,t)
# 회전 : 회전안된D or 회전된 C 회전하면서
elif (arr[ny][nx] == 'D' and not ns&(1<<(nx+ny*W))) or (arr[ny][nx] == 'C' and ns&(1<<(nx+ny*W))):
update(nx,ny,ns,t)
# 가로이동
elif not is_ver and (arr[y][x] == 'A' or (arr[y][x] == 'C' and s&(1<<(x+y*W))) or (arr[y][x] == 'D' and not s&(1<<(x+y*W)))):
# 회전 x : 다음 A or 회전안된D or 회전된C
update(x,y,ns,t) # 제자리에서 회전
if (arr[ny][nx] == 'A') or (arr[ny][nx] == 'D' and not s&(1<<(nx+ny*W))) or (arr[ny][nx] == 'C' and s&(1<<(nx+ny*W))):
update(nx,ny,s,t) # 회전 안하고 다음칸
# 회전 : 회전안된 C or 회전된 D 회전하면서
elif (arr[ny][nx] == 'C' and not ns&(1<<(nx+ny*W))) or (arr[ny][nx] == 'D' and ns&(1<<(nx+ny*W))):
update(nx,ny,ns,t)
print(answer)
코멘트
- 함수로 코드 줄이다가 오타나서 한참 찾았...
- 조건문의 경우도 간단하게 함수 써서 딕셔너리로 매핑하는게 필요할듯.
'Algorithm > Graph' 카테고리의 다른 글
[파이썬] 백준 1981 : 배열에서 이동 (플레5) (0) | 2024.11.28 |
---|---|
[파이썬] 백준 2325 : 개코전쟁 (플레5) (0) | 2024.11.27 |
[파이썬] 백준 28032: Filed Day (플레2) (0) | 2024.11.26 |
[파이썬] 백준 20304 : 비밀번호 제작 (플레5) (0) | 2024.11.23 |
[파이썬] 백준 3197 : 백조의 호수 (플레5) (0) | 2024.11.23 |
[파이썬] 백준 14868 : 문명 (플레4) (0) | 2024.11.22 |
[파이썬] 백준 11779 : 최소비용 구하기 2 (골드3) (0) | 2024.11.21 |
댓글