[파이썬] 백준 2206 : 벽 부수고 이동하기 (골드3)
2206번: 벽 부수고 이동하기
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로
www.acmicpc.net
문제
풀이
0. 방향성 생각
- 벽을 한개까지 부술 수 있다.
- 벽을 부순 상태 / 부수지 않은 상태 2가지로 나눈다.
- visit 배열의 차원을 하나 늘린다.
- 방향으로 나누는 state가 아니어서 위로 쌓는 방식으로 visit 층수를 늘린다.
1. 입력
from collections import deque
import sys
input = lambda: sys.stdin.readline().rstrip()
h,w = map(int,input().split())
arr = [list(map(int,input())) for _ in range(h)]
visit = [[[-1]*w for _ in range(h)] for _ in range(2)]
dire = [(1,0),(0,1),(-1,0),(0,-1)]
- 2층짜리 격자 visit을 만들어준다.
- 4가지 방향 정의
2. BFS
q = deque([(0,0,0)])
visit[0][0][0] = 1
while q:
x,y,t = q.popleft() # 벽을 t개까지 부수상태
for dx,dy in dire:
nx = x + dx
ny = y + dy
if 0<=nx<w and 0<=ny<h and visit[t][ny][nx] == -1: # 방문안했으면
if not arr[ny][nx]: # 그냥 갈 수 있는 경우
visit[t][ny][nx] = visit[t][y][x] + 1 # 옆으로 이동
q.append((nx,ny,t))
elif t == 0 and arr[ny][nx] == 1: # 벽을 안뚫은 경우 다음칸이 벽일 때
visit[1][ny][nx] = visit[0][y][x] + 1
q.append((nx,ny,1))
- 큐에 좌표와 현재 탐색중인 말의 상태 t를 넣어준다
- t = 0 : 벽 안부순 상태 / t = 1 : 벽 부순상태
- inner / not visit - > 벽을 만난 경우 / 만나지 않은 경우
- 벽을 만나지 않은 경우에는 visit + 1 을 해주고
- 벽을 만난 경우에는 t = 0인 경우에만 탐색이 가능하게 해주고 t를 1로 변경해준다.
3. 출력
answer = [visit[i][-1][-1] for i in range(2)]
print(max(answer) if -1 in answer else min(answer))
- 벽을 안부수고 도착지점에 도달한 경우 / 벽을 부수고 도착지점에 도달한 경우
- 두 가지중 작은 경우를 출력한다.
전체코드
from collections import deque
import sys
input = lambda: sys.stdin.readline().rstrip()
h,w = map(int,input().split())
arr = [list(map(int,input())) for _ in range(h)]
visit = [[[-1]*w for _ in range(h)] for _ in range(2)]
dire = [(1,0),(0,1),(-1,0),(0,-1)]
q = deque([(0,0,0)])
visit[0][0][0] = 1
while q:
x,y,t = q.popleft() # 벽을 t개까지 부수상태
for dx,dy in dire:
nx = x + dx
ny = y + dy
if 0<=nx<w and 0<=ny<h and visit[t][ny][nx] == -1: # 방문안했으면
if not arr[ny][nx]: # 그냥 갈 수 있는 경우
visit[t][ny][nx] = visit[t][y][x] + 1 # 옆으로 이동
q.append((nx,ny,t))
elif t == 0 and arr[ny][nx] == 1: # 벽을 안뚫은 경우 다음칸이 벽일 때
visit[1][ny][nx] = visit[0][y][x] + 1
q.append((nx,ny,1))
answer = [visit[i][-1][-1] for i in range(2)]
print(max(answer) if -1 in answer else min(answer))
코멘트
웰노운은 10분 이내로 줄이기.... 약간 느리다
'Algorithm > Graph' 카테고리의 다른 글
[파이썬] 프로그래머스 : 미로 탈출 (Lv.4) (0) | 2023.12.03 |
---|---|
[파이썬] 백준 2982 : 국왕의 방문 (골드2) (0) | 2023.11.22 |
[파이썬] 백준 2251: 물통 (골드5) (0) | 2023.11.21 |
[파이썬] 백준 1926 : 그림 (실버1) (0) | 2023.11.10 |
[파이썬] 백준 1303 : 전쟁 - 전투 (실버1) (0) | 2023.11.10 |
[파이썬] 백준 1833 : 고속철도 설계하기 (골드3) (0) | 2023.11.05 |
[파이썬] 백준 2151 : 거울설치 (골드3) (0) | 2023.10.08 |
댓글