[파이썬] 백준 17090 : 미로 탈출하기 (골드3)
17090번: 미로 탈출하기
크기가 N×M인 미로가 있고, 미로는 크기가 1×1인 칸으로 나누어져 있다. 미로의 각 칸에는 문자가 하나 적혀있는데, 적혀있는 문자에 따라서 다른 칸으로 이동할 수 있다. 어떤 칸(r, c)에 적힌 문
www.acmicpc.net
문제
풀이
0. 방향성 생각
DP 태그 있어서 이용할 수도 있는데 내리막길 문제처럼 경로의 수를 카운트 하는게 아니라서 안써도 무방하다.
1. padding : 외곽 'x'로 채우기
2. 탈출 가능한 외곽지점 큐에 추가
3. 탈출 가능 지점에서 BFS 진행.
오른쪽 탐색 -> L이면 탈출 가능
왼쪽 탐색 -> R이면 탈출 가능
위쪽 탐색 -> D면 탈출 가능
아래쪽 탐색 -> U면 탈출 가능
4. 남은 'x'가 아닌 문자 카운트 : 탈출 불가
5. h*w - 탈출불가 개수
1. 입력
from collections import deque
import sys
input = lambda : sys.stdin.readline().rstrip()
h,w = map(int,input().split())
arr = []
for i in range(h+2):
if i==0 or i==h+1:
arr.append(['x']*(w+2))
else:
temp = list(input())
temp = ['x'] + temp + ['x']
arr.append(temp)
외곽 padding 해주기
2. 탈출 가능한 외곽지점 탐색
q = deque()
for i in (1,h):
for j in range(1,w+1):
if i==1 and arr[i-1][j] == 'x' and arr[i][j] == 'U':
q.append((j,i))
if i==h and arr[i+1][j] == 'x' and arr[i][j] == 'D':
q.append((j,i))
for i in range(1,h+1):
for j in (1,w):
if j==1 and arr[i][j-1] == 'x' and arr[i][j] == 'L':
q.append((j,i))
if j==w and arr[i][j+1] == 'x' and arr[i][j] == 'R':
q.append((j,i))
외곽에서만 탐색해서 탈출 가능 유무를 확인하고 가능하면 큐에 추가한다.
3. BFS 진행
step = [[1,-1,0,0],[0,0,1,-1]]
while q:
x,y = q.popleft()
arr[y][x] = 'x'
for i in range(4):
nx = x + step[0][i]
ny = y + step[1][i]
if 0<=nx<=w+1 and 0<=ny<=h+1:
if i==0 and arr[ny][nx] == 'L' :
q.append((nx,ny))
if i==1 and arr[ny][nx] == 'R' :
q.append((nx,ny))
if i==2 and arr[ny][nx] == 'U' :
q.append((nx,ny))
if i==3 and arr[ny][nx] == 'D' :
q.append((nx,ny))
탈출 가능지점에서 오른쪽으로 갔는데 그 지점이 L이면 탈출가능 지점으로 올 수 있다.
탈출 가능지점을 'x'로 바꿔주면서 탐색하면 탐색이 끝난 후에 탈출 가능 지점들은 모두 'x'로 바뀐다.
동작 과정
더보기
테스트 케이스2의 탐색 과정을 나타내면 다음과 같다
다음좌표, 다음 좌표값, i (오른쪽 왼쪽 아래 위 순서이다.)
['x', 'x', 'x', 'x', 'x']
['x', 'D', 'D', 'R', 'x']
['x', 'D', 'L', 'U', 'x']
['x', 'L', 'L', 'L', 'x']
['x', 'x', 'x', 'x', 'x']
deque([(3, 1), (1, 3)])
(4, 1) x 0
(2, 1) D 1
(3, 2) U 2
(3, 0) x 3
['x', 'x', 'x', 'x', 'x']
['x', 'D', 'D', 'x', 'x']
['x', 'D', 'L', 'U', 'x']
['x', 'L', 'L', 'L', 'x']
['x', 'x', 'x', 'x', 'x']
deque([(1, 3), (3, 2)])
(2, 3) L 0
(0, 3) x 1
(1, 4) x 2
(1, 2) D 3
['x', 'x', 'x', 'x', 'x']
['x', 'D', 'D', 'x', 'x']
['x', 'D', 'L', 'U', 'x']
['x', 'x', 'L', 'L', 'x']
['x', 'x', 'x', 'x', 'x']
deque([(3, 2), (2, 3), (1, 2)])
(4, 2) x 0
(2, 2) L 1
(3, 3) L 2
(3, 1) x 3
['x', 'x', 'x', 'x', 'x']
['x', 'D', 'D', 'x', 'x']
['x', 'D', 'L', 'x', 'x']
['x', 'x', 'L', 'L', 'x']
['x', 'x', 'x', 'x', 'x']
deque([(2, 3), (1, 2)])
(3, 3) L 0
(1, 3) x 1
(2, 4) x 2
(2, 2) L 3
['x', 'x', 'x', 'x', 'x']
['x', 'D', 'D', 'x', 'x']
['x', 'D', 'L', 'x', 'x']
['x', 'x', 'x', 'L', 'x']
['x', 'x', 'x', 'x', 'x']
deque([(1, 2), (3, 3)])
(2, 2) L 0
(0, 2) x 1
(1, 3) x 2
(1, 1) D 3
['x', 'x', 'x', 'x', 'x']
['x', 'D', 'D', 'x', 'x']
['x', 'x', 'L', 'x', 'x']
['x', 'x', 'x', 'L', 'x']
['x', 'x', 'x', 'x', 'x']
deque([(3, 3), (2, 2), (1, 1)])
(4, 3) x 0
(2, 3) x 1
(3, 4) x 2
(3, 2) x 3
['x', 'x', 'x', 'x', 'x']
['x', 'D', 'D', 'x', 'x']
['x', 'x', 'L', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
deque([(2, 2), (1, 1)])
(3, 2) x 0
(1, 2) x 1
(2, 3) x 2
(2, 1) D 3
['x', 'x', 'x', 'x', 'x']
['x', 'D', 'D', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
deque([(1, 1), (2, 1)])
(2, 1) D 0
(0, 1) x 1
(1, 2) x 2
(1, 0) x 3
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'D', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
deque([(2, 1)])
(3, 1) x 0
(1, 1) x 1
(2, 2) x 2
(2, 0) x 3
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
['x', 'x', 'x', 'x', 'x']
deque([])
4. 정답 출력
answer = h*w
for i in range(1,h+1):
for j in range(1,w+1):
if arr[i][j] != 'x' :
answer += -1
print(answer)
전체 h*w개 중 x가 아닌 개수들을 빼면 탈출 가능한 지점의 수이다.
전체코드
from collections import deque
import sys
input = lambda : sys.stdin.readline().rstrip()
h,w = map(int,input().split())
arr = []
for i in range(h+2):
if i==0 or i==h+1:
arr.append(['x']*(w+2))
else:
temp = list(input())
temp = ['x'] + temp + ['x']
arr.append(temp)
q = deque()
for i in (1,h):
for j in range(1,w+1):
if i==1 and arr[i-1][j] == 'x' and arr[i][j] == 'U':
q.append((j,i))
if i==h and arr[i+1][j] == 'x' and arr[i][j] == 'D':
q.append((j,i))
for i in range(1,h+1):
for j in (1,w):
if j==1 and arr[i][j-1] == 'x' and arr[i][j] == 'L':
q.append((j,i))
if j==w and arr[i][j+1] == 'x' and arr[i][j] == 'R':
q.append((j,i))
step = [[1,-1,0,0],[0,0,1,-1]]
while q:
x,y = q.popleft()
arr[y][x] = 'x'
for i in range(4):
nx = x + step[0][i]
ny = y + step[1][i]
if 0<=nx<=w+1 and 0<=ny<=h+1:
if i==0 and arr[ny][nx] == 'L' :
q.append((nx,ny))
if i==1 and arr[ny][nx] == 'R' :
q.append((nx,ny))
if i==2 and arr[ny][nx] == 'U' :
q.append((nx,ny))
if i==3 and arr[ny][nx] == 'D' :
q.append((nx,ny))
answer = h*w
for i in range(1,h+1):
for j in range(1,w+1):
if arr[i][j] != 'x' :
answer += -1
print(answer)
코멘트
물 골3
'Algorithm > Graph' 카테고리의 다른 글
[파이썬] 백준 2481 : 해밍 경로 (골드2) (0) | 2023.08.12 |
---|---|
[파이썬] 백준 17244 : 아맞다우산 (골드2) (0) | 2023.08.09 |
[파이썬] 백준 9019 : DSLR (골드4) (0) | 2023.08.03 |
[파이썬] 백준 1525 : 퍼즐 (골드2) (0) | 2023.07.30 |
[파이썬] 프로그래머스 : 단어 변환 (Lv.2) (0) | 2023.07.20 |
[파이썬] 백준 3184, 3187 : 양, 양치기 꿍 (실버1) (0) | 2023.07.13 |
[파이썬] 백준 연구소3 : 17142 (골드3) (0) | 2023.07.12 |
댓글