Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- BOJ
- ssafy
- java
- 다이나믹프로그래밍
- 코딩테스트
- SSAFY수료식
- 파이썬
- dfs
- 항해
- BFS
- programmers
- 문자열
- DP
- 브루트포스
- 99클럽
- 구현
- til
- 위상정렬
- 99일지
- 알고리즘
- 너비우선탐색
- 백준
- 개발자스터디
- 깊이우선탐색
- 싸피
- python
- 자바
- 백트래킹
- 삼성청년SW아카데미
- 프로그래머스
Archives
- Today
- Total
EunJng
[BOJ] 2206 벽 부수고 이동하기 | Python 본문
문제
백준 2206번 벽 부수고 이동하기 | 골드3
https://www.acmicpc.net/problem/2206
2206번: 벽 부수고 이동하기
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로
www.acmicpc.net
- 알고리즘 분류 : 그래프 이론 | 그래프 탐색 | 너비 우선 탐색(BFS)
풀이 과정
파이썬 풀이
from collections import deque
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
def bfs(x, y):
q = deque()
q.append((x, y, 0))
visited[x][y][0] = 1
while q:
x, y, wall = q.popleft()
# x, y좌표와 wall(벽 부쉈는지 여부)
if x == N-1 and y == M-1:
return visited[x][y][wall]
# 도착했다면 벽 부순 여부에 따른 visited 값 return
for d in range(4):
nx = x + dx[d]
ny = y + dy[d]
if 0 <= nx < N and 0 <= ny < M and not visited[nx][ny][wall]:
if not arr[nx][ny]:
# 방문한 적 없고 이동할 수 있으면(벽이 아니라면)
# (x, y) 값 + 1의 경로 남기고 q에 추가하기
visited[nx][ny][wall] = visited[x][y][wall]+1
q.append((nx, ny, wall))
if not wall and arr[nx][ny]:
# 만약 벽이 있는 곳인데 wall == 0이면 벽 부순 적이 없으므로 부수기 가능
# 벽 부쉈다는 의미로 visited[nx][ny] 중 인덱스 1의 위치에 경로 남기기
visited[nx][ny][1] = visited[x][y][wall]+1
q.append((nx, ny, 1))
# wall = 1로 하여 벽 부쉈다는 표시
# 따라서 이후로는 벽이 있어도 추가로 벽을 부수지는 못함
return -1
# 불가능한 경우
N, M = map(int, input().split())
arr = [list(map(int, input())) for _ in range(N)]
visited = [[[0, 0] for _ in range(M)] for _ in range(N)]
# 벽 부수지 않았을 때, 벽 부수고 난 뒤
print(bfs(0, 0))
- 3차원 배열의 visited를 통해 하나의 벽을 부순 여부에 따른 경로 기록
- 3차원 배열에 익숙하지 않을 때 풀었던 문제라 아이디어를 떠올리기도 힘들었고, 이해하는 과정에서도 시간이 다소 걸렸다.
예를 들어, 질문 게시판에 있는 반례 중 아래 반례로 코드를 실행시켜 visited를 확인해본다면 아래와 같은 결과가 나온다.
5 8
01000000
01010000
01010000
01010011
00010010
[[1, 3], [0, 12], [11, 3], [12, 4], [13, 5], [14, 6], [15, 7], [16, 8]]
[[2, 4], [0, 11], [10, 4], [0, 15], [14, 6], [15, 7], [16, 8], [17, 9]]
[[3, 5], [0, 10], [9, 5], [0, 16], [15, 7], [16, 8], [17, 9], [18, 10]]
[[4, 6], [0, 9], [8, 6], [0, 17], [16, 8], [17, 9], [0, 18], [0, 19]]
[[5, 7], [6, 6], [7, 7], [0, 18], [17, 9], [18, 10], [0, 19], [0, 20]]
즉 왼쪽은 벽을 뚫기 전 bfs를 통해 최단경로를 기록하던 것이지만 (N, M)의 위치까지 도달하지는 못하였고,
오른쪽은 벽을 뚫은 뒤 bfs를 통해 새로운 최단 경로를 기록한 것이다. 이 경우 (N, M)의 위치까지 도달하였으므로 결과는 20이 된다.
'PROBLEM > BAEKJOON' 카테고리의 다른 글
[BOJ] 10818 최소, 최대 | Java (0) | 2023.05.06 |
---|---|
[BOJ] 17825 주사위 윷놀이 | Python (1) | 2023.05.06 |
[BOJ] 2533 사회망 서비스(SNS) | Python (0) | 2023.05.05 |
[BOJ] 11723 집합 | Python (1) | 2023.05.02 |
[BOJ] 2525 | 오븐 시계 | Java (0) | 2023.05.01 |