너와!나의!알고!리즘!/백준

[백준 # 1261, Python] 알고스팟

moongchi98 2021. 5. 14. 00:33

[문제]

알고스팟 운영진이 모두 미로에 갇혔다. 미로는 N*M 크기이며, 총 1*1크기의 방으로 이루어져 있다. 미로는 빈 방 또는 벽으로 이루어져 있고, 빈 방은 자유롭게 다닐 수 있지만, 벽은 부수지 않으면 이동할 수 없다.

알고스팟 운영진은 여러명이지만, 항상 모두 같은 방에 있어야 한다. 즉, 여러 명이 다른 방에 있을 수는 없다. 어떤 방에서 이동할 수 있는 방은 상하좌우로 인접한 빈 방이다. 즉, 현재 운영진이 (x, y)에 있을 때, 이동할 수 있는 방은 (x+1, y), (x, y+1), (x-1, y), (x, y-1) 이다. 단, 미로의 밖으로 이동 할 수는 없다.

벽은 평소에는 이동할 수 없지만, 알고스팟의 무기 AOJ를 이용해 벽을 부수어 버릴 수 있다. 벽을 부수면, 빈 방과 동일한 방으로 변한다.

만약 이 문제가 알고스팟에 있다면, 운영진들은 궁극의 무기 sudo를 이용해 벽을 한 번에 다 없애버릴 수 있지만, 안타깝게도 이 문제는 Baekjoon Online Judge에 수록되어 있기 때문에, sudo를 사용할 수 없다.

현재 (1, 1)에 있는 알고스팟 운영진이 (N, M)으로 이동하려면 벽을 최소 몇 개 부수어야 하는지 구하는 프로그램을 작성하시오.

[풀이]

뭐지..생각보다 엄청 쉽게 풀렸다.. 처음에는 최단거리 + 최소 뿌심이라고 생각해서(나쁜 버릇 데헷^~^) 무조껀 우측, 아래로만 이동하면 된다고 생각했는데, 그러면 답이 나오지 않는다. 

00000

11110

00000

01111

00000 

이런 예제를 통과 못함! 내 경우에는 답이 1이나오는데, 실제 답안은 0이다!

즉, 4방향 탐색을 모두 하고, 그때 visit[nr][nc] > visit[r][c] + arr[nr][nc] 를 고려해준다. 즉, arr에 벽이면 그걸 부시고 가는게 좋은지 아니면 기존 방법이 좋은지 정하는것! 그래고 가장 중요한 것은, 만약 방문했더라도 부시고 가는게 더 좋은 경우에는 q에 들어갈 수 있도록, dp조건 만족하면 q에 넣어주도록 배치했다.

🐰 간단한 DFS+DP?

 

from sys import stdin
from collections import deque
def bfs():
    visit =[[123456789]*M for _ in range(N)]
    visit[0][0] = 0
    while q:
        r,c = q.popleft()
        for dr,dc in [(1,0),(0,1),(-1,0),(0,-1)]:
            nr = r + dr
            nc = c + dc
            if 0<=nr<N and 0<=nc<M:
                if visit[nr][nc] > visit[r][c] + arr[nr][nc]:
                    visit[nr][nc] = visit[r][c] + arr[nr][nc]
                    q.append((nr,nc))
    return visit[N-1][M-1]



M,N = map(int,stdin.readline().split())
arr = [list(map(int,stdin.readline().strip())) for _ in range(N)]
q = deque()
q.append((0,0))
print(bfs())