[백준 알고리즘] 2206번: 벽 부수고 이동하기 (Python / 파이썬)

2024. 1. 22. 00:35·알고리즘/백준


문제 접근

최단 경로를 구하는 문제이므로 bfs가 적합하다.

n * m 행렬이 주어지고, 시작점이 정해져 있기에 생각보다 간단한 문제라고 생각했다.

벽(1)을 한 번만 부술 수 있으므로, 모든 벽들을 하나씩 부숴보고 bfs를 각각 돌려 최솟값을 구하면 된다고 생각했지만,

n , m <= 1,000 이므로, 단순히만 생각해도 벽이 최대 nm -2(시작,종료점)개 존재할 수 있어 bfs를 1,000,000번 수행해야 하므로 시간초과가 날 것이다.

 

따라서 visited 배열을 3차원으로 만들어 벽을 부수고 가고 있는 경로인지, 벽을 아직 부수지 않고 가고 있는 경로인지 체크하는 방법을 사용했다.

이렇게 하면 bfs를 한 번만 수행하고 문제를 풀 수 있다.

 

bfs는 다음과 같이 진행된다.

1. 큐에 시작점 추가
2. 큐가 있는 동안 반복
1) popleft 한 요소의 상하좌우 탐색 (이때, 종료지점 확인)
2) matrix[nx][ny]가 1인 경우 : 아직 1을 부수지 않았다면 부수기, 큐에 추가
3) matrix[nx][ny]가 0인 경우: 방문하지 않았다면 큐에 추가
3. 종료가 되지 않았다면 -1 리턴 (도달하지 못하는 경우)

최단 경로 계산은 이전 visited 값에 + 1 해주어 계산한다.

 

정답 코드
#2206번: 벽 부수고 이동하기

import sys
from collections import deque

def bfs(matrix, visited):
    queue = deque()
    queue.append((0, 0, 0))
    visited[0][0][0] = 1
    dx, dy = [1, 0, 0, -1], [0, 1, -1, 0]

    while queue:
        x, y, z = queue.popleft()
        if x == n - 1 and y == m - 1:
            return visited[x][y][z]
        for i in range(4):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if matrix[nx][ny] == '1':
                    if z == 0:
                        queue.append((nx, ny, 1))
                        visited[nx][ny][1] = visited[x][y][0] + 1
                else:
                    if visited[nx][ny][z] == 0:
                        queue.append((nx, ny, z))
                        visited[nx][ny][z] = visited[x][y][z] + 1
    return -1

n, m = map(int, sys.stdin.readline().split())
matrix = [list(sys.stdin.readline().rstrip()) for _ in range(n)]

visited = [[[0, 0] for _ in range(m)] for _ in range(n)]

print(bfs(matrix, visited))

 

2206번: 벽 부수고 이동하기

N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로

www.acmicpc.net

 

저작자표시 (새창열림)

'알고리즘 > 백준' 카테고리의 다른 글

[백준 알고리즘] 15649번: N과 M(1) (Python / 파이썬)  (0) 2024.01.24
[백준 알고리즘] 7569번: 토마토 (Python / 파이썬)  (0) 2024.01.22
[백준 알고리즘] 10026번: 적록색약 (Python / 파이썬)  (2) 2024.01.22
[백준 알고리즘] 1780번: 종이의 개수 (Python / 파이썬)  (0) 2024.01.22
[백준 알고리즘] 2630번: 색종이 만들기 (Python / 파이썬)  (0) 2024.01.22
'알고리즘/백준' 카테고리의 다른 글
  • [백준 알고리즘] 15649번: N과 M(1) (Python / 파이썬)
  • [백준 알고리즘] 7569번: 토마토 (Python / 파이썬)
  • [백준 알고리즘] 10026번: 적록색약 (Python / 파이썬)
  • [백준 알고리즘] 1780번: 종이의 개수 (Python / 파이썬)
gyujh
gyujh
개발 공부 블로그
  • gyujh
    규
    gyujh
  • 전체
    오늘
    어제
    • 분류 전체보기 (86)
      • Backend&DB (3)
      • CS (5)
        • 컴퓨터구조 (1)
        • 소프트웨어공학 (4)
      • JavaScript (2)
      • Git (2)
      • 알고리즘 (73)
        • 개념 (3)
        • 백준 (70)
      • Projects (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    런타임
    재귀
    정답
    시간초과
    스택
    답안
    너비우선탐색
    딕셔너리
    에러
    숏코딩
    프로그래머스
    BOJ
    정렬
    알고리즘
    풀이
    구현
    문자열
    답
    algorithm
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
gyujh
[백준 알고리즘] 2206번: 벽 부수고 이동하기 (Python / 파이썬)
상단으로

티스토리툴바