728x90
풀이과정
해당 문제는 방문 표시만 제대로 하면 쉽게 해결할 수 있는 문제이다.
물론 방문 표시가 생각보다 까다롭다.
😂
시작점에서 끝점까지 도달하는 최단 거리는 너비 우선 탐색(BFS)으로 구현하면 된다.
그렇다면 이 문제의 핵심은 방문 표시이다.
탈출을 하기 위해서는 '.' 공간만 이용할 수 있다.
물론 주어진 n*m 행렬 맵에서는 키라는 특이한 요소를 첨가했다.
키의 종류는 a, b, c, d, e, f 총 6가지이며,
키의 종류 따른 문의 종류도 A, B, C, D, E, F 총 6가지이다.
문제에서는 탈출구까지 가는 길에 문이 있으면
해당 문에 맞는 키 값을 소유하고 있어야 한다.
그렇기 때문에 BFS 탐색할 때
방문 표시를 가지고 있는 키 값들에 따라 해주어야 한다.
키의 종류는 총 6가지이다.
그렇기 때문에 방문 표시도 2^6 = 64개만큼 생성해주면 된다.
1. '0'부터 BFS 탐색을 시작한다.
2. 새롭게 이동한 곳이 '1' 이거나 '.'이면
해당 키 값에 따른 방문 표시를 해주고
q에 이동 좌표를 삽입해준다.
3. 새롭게 이동한 곳이 'abcdef'에 key가 존재하는 경우,
현재 key에서 or 연산을 통해 key를 획득하고
q에 업데이트 키와 함께 삽입해준다.
4. 새롭게 이동한 곳이 "ABCDEF"에 key가 존재하는 경우,
현재 key에 and 연산을 통해 문을 통과할 수 있는지 확인해준다.
5. '1'에 도달할 경우 cnt를 리턴, 도달하지 못할 경우 while문 종료 및 -1 리턴
풀이 코드
from collections import deque
def bfs() :
start = None
for i in range(n) :
if start != None : break
for j in range(m) :
if board[i][j] == "0" :
board[i][j] = '.'
start = (i,j)
x,y = start
q = deque([(x,y,0,0)])
visited = [[[0] * 64 for _ in range(m)] for _ in range(n)]
dx,dy = [0,0,-1,1],[-1,1,0,0]
visited[x][y][0] = True
while q :
x,y,cnt,key = q.popleft()
if board[x][y] == "1" :
return cnt
else :
for i in range(4) :
nx,ny = x + dx[i],y + dy[i]
if 0 <= nx < n and 0<= ny < m and board[nx][ny] != '#' and not visited[nx][ny][key] :
if board[nx][ny] == '.' :
visited[nx][ny][key] = True
q.append((nx,ny,cnt+1,key))
elif board[nx][ny] == "1" :
return cnt+1
elif board[nx][ny] in "ABCDEF" and key & 1 << (ord(board[nx][ny])- 65):
visited[nx][ny][key] = True
q.append((nx,ny,cnt+1,key))
elif board[nx][ny] in "abcdef" and not visited[nx][ny][key|(1 << ord(board[nx][ny]) - 97)] :
visited[nx][ny][key | (1 << ord(board[nx][ny]) - 97)] = True
q.append((nx,ny,cnt+1,key | (1 << ord(board[nx][ny]) - 97)))
return -1
n,m = map(int,input().split())
board = [list(input().strip()) for _ in range(n)]
print(bfs())
'Language > Python' 카테고리의 다른 글
[Python][백준 2133][DP] 타일 채우기 - 컴도리돌이 (0) | 2022.07.26 |
---|---|
[Python][백준 20437][문자열] 문자열 게임 2 - 컴도리돌이 (0) | 2022.07.25 |
[Python][백준 10972][알고리즘 - next permutation] 다음 순열 - 컴도리돌이 (0) | 2022.07.21 |
[Python][백준 23817][BFS, DFS, BruteForce] 포항항 - 컴도리돌이 (0) | 2022.06.26 |
[Python][백준 14438][세그먼트 트리] 수열과 쿼리 17 - 컴도리돌이 (0) | 2022.06.25 |