728x90
반응형
https://www.acmicpc.net/problem/14442
14442번: 벽 부수고 이동하기 2
첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 1,000), K(1 ≤ K ≤ 10)이 주어진다. 다음 N개의 줄에 M개의 숫자로 맵이 주어진다. (1, 1)과 (N, M)은 항상 0이라고 가정하자.
www.acmicpc.net
문제 해결
- (0,0)에서 (n-1,m-1)까지 이동하는 문제
- 갈 수 있는 길이 있고 없는 길이 있다. 하지만 예외적으로 k번 갈 수 없는 길을 갈 수 있다.
- 따라서 visited[i][j]에서 예외포인트 k번 까지 가능하다는 것에서 visited[i][j][k]의 방문 여부를 확인하는 것이 편하다.
- visited[i][j][k]의 값은 (i,j)까지 벽을 깰 수 있는 횟수 k번 남기고 이동한 횟수를 말한다.
- 갈 수 없는 길을 한 번 소비할 때마다 visited[i][j][k]에서 visited[i][j][k-1]이 되고 값도 +1을 처리하면 된다.
- 이렇게 하면 좋은점은 이동횟수 cnt와 벽 부순 횟수 b와 따로 생각하지 않고 그래프로 묶어서 생각할 수 있다는 것이다.
- 사실 python3로 돌리면 시간초과가 나고 pypy3로 돌리면 통과한다. 어떻게 더 줄일 수 있을지는 고민해봐야 하는 상황
CODE
import sys
input = sys.stdin.readline
from collections import deque
n,m,k = map(int, input().split())
A = []
for _ in range(n):
A.append([int(c) for c in str(input().rstrip())])
move = [(0,1),(1,0),(-1,0),(0,-1)]
def bfs():
que = deque()
que.append((0,0,k)) # 시작점(0,0), 뚫을 수 있는 벽의 수
visited = [[[0]*(k+1) for _ in range(m)] for _ in range(n)]
visited[0][0][k] = 1
while que:
r,c,b = que.popleft()
if r == n-1 and c == m-1:
return visited[r][c][b]
for next in move:
new_r = r + next[0]
new_c = c + next[1]
if 0<=new_r<=n-1 and 0<=new_c<=m-1:
if b>=1 and visited[new_r][new_c][b-1] == 0 and A[new_r][new_c]==1:
visited[new_r][new_c][b-1] = visited[r][c][b]+1
que.append((new_r,new_c,b-1))
elif visited[new_r][new_c][b]==0 and A[new_r][new_c] ==0:
visited[new_r][new_c][b] = visited[r][c][b]+1
que.append((new_r,new_c,b))
else:
return -1
ans = bfs()
print(ans)
728x90
반응형
'알고리즘 > [python] 백준 BOJ' 카테고리의 다른 글
[python] 백준 1343 폴리오미노 (0) | 2023.03.14 |
---|---|
[python] 백준 2011 암호코드 (0) | 2023.03.14 |
[python] 백준 1213 팰린드롬 만들기 (0) | 2023.03.13 |
[python] 백준 1965 상자넣기 (0) | 2023.03.12 |
[python] 백준 1915 가장 큰 정사각형 (0) | 2023.03.12 |
댓글