BOJ

[골드 3] 2206번: 벽 부수고 이동하기

2022. 9. 24. 09:23
목차
  1. 문제
  2. 입력
  3. 출력
  4. 풀이
  5. 내가 작성한 소스코드
  6. 남이 작성한 소스코드
  7. 피드백
728x90

Original Source: https://www.acmicpc.net/problem/2206

 

2206번: 벽 부수고 이동하기

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

www.acmicpc.net


문제

N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로로 이동하려 한다. 최단경로는 맵에서 가장 적은 개수의 칸을 지나는 경로를 말하는데, 이때 시작하는 칸과 끝나는 칸도 포함해서 센다.

만약에 이동하는 도중에 한 개의 벽을 부수고 이동하는 것이 좀 더 경로가 짧아진다면, 벽을 한 개 까지 부수고 이동하여도 된다.

한 칸에서 이동할 수 있는 칸은 상하좌우로 인접한 칸이다.

맵이 주어졌을 때, 최단 경로를 구해 내는 프로그램을 작성하시오.

입력

첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 1,000)이 주어진다. 다음 N개의 줄에 M개의 숫자로 맵이 주어진다. (1, 1)과 (N, M)은 항상 0이라고 가정하자.

출력

첫째 줄에 최단 거리를 출력한다. 불가능할 때는 -1을 출력한다.


풀이

핵심은 벽을 부수지 않았을 때와 벽을 부쉈을 때를 구분하는 것이다.

두 개의 정수형 방문 List를 만들어서 벽을 부수지 않았을 때는 첫 번째 List에, 부쉈을 때는 두 번째 List에 이동 횟수를 저장해야 한다.

내가 작성한 소스코드

import sys
from collections import deque
r = sys.stdin.readline


def bfs(maze, visited0, visited1, size):
    n = size[0]; m = size[1]
    d = ((-1, 0), (0, -1), (1, 0), (0, 1))
    
    q = deque()
    q.append(((0, 0), 0))
    visited0[0][0] = 1

    while q:
        ((y, x), is_broken) = q.popleft()

        if (y, x) == (n-1, m-1):
            if is_broken == 0:
                print(visited0[y][x])
            else:
                print(visited1[y][x])
            
            return

        for (dy, dx) in d:
            ny = y + dy
            nx = x + dx

            if (ny < 0 or ny > n-1) or (nx < 0 or nx > m-1):
                continue

            if is_broken == 0 and visited0[ny][nx] == -1:
                if maze[ny][nx] == 0:
                    q.append(((ny, nx), 0))
                    visited0[ny][nx] = visited0[y][x] + 1
                else:
                    q.append(((ny, nx), 1))
                    visited1[ny][nx] = visited0[y][x] + 1

            elif (is_broken == 1 and visited1[ny][nx] == -1) and maze[ny][nx] == 0:
                q.append(((ny, nx), 1))
                visited1[ny][nx] = visited1[y][x] + 1

    print(-1)
    return


n, m = map(int, r().split())
maze = []
for _ in range(n):
    maze.append(list(map(int, r().rstrip())))
visited0 = [[-1] * m for _ in range(n)]
visited1 = [[-1] * m for _ in range(n)]

bfs(maze, visited0, visited1, (n, m))

남이 작성한 소스코드

koosaga 님:
https://www.acmicpc.net/source/5726145

피드백

  • 두 개의 2차원 방문 List를 한 개의 3차원 방문 List로 축약할 수 있다. 메모리 제한이 있으면 유용할 것 같다. 
저작자표시 (새창열림)

'BOJ' 카테고리의 다른 글

[골드 3] 14442번: 벽 부수고 이동하기 2  (0) 2022.09.27
[골드 2] 16946번: 벽 부수고 이동하기 4  (1) 2022.09.25
[실버 3] 15656번: N과 M (7)  (0) 2022.09.22
[실버 5] 1476번: 날짜 계산  (0) 2022.09.21
[실버 3] 15652번: N과 M (4)  (0) 2022.09.21
  • 문제
  • 입력
  • 출력
  • 풀이
  • 내가 작성한 소스코드
  • 남이 작성한 소스코드
  • 피드백
'BOJ' 카테고리의 다른 글
  • [골드 3] 14442번: 벽 부수고 이동하기 2
  • [골드 2] 16946번: 벽 부수고 이동하기 4
  • [실버 3] 15656번: N과 M (7)
  • [실버 5] 1476번: 날짜 계산
Park Joonyoung
Park Joonyoung
개발 블로그
Park Joonyoung
DevJoon
Park Joonyoung
전체
오늘
어제
  • 분류 전체보기 (88)
    • BOJ (41)
      • 틀렸습니다 (6)
    • 알고리즘 (4)
    • C++ (2)
    • Python (1)
    • 토이 프로젝트 (0)
    • 선형대수학 (1)
    • 기타 (3)
    • 에세이 (4)
    • [개인 보관용] (32)
      • 이코테 강의 정리 (0)
      • 알고리즘(old) (0)
      • 단변수미적분학 (0)
      • 다변수미적분학 (0)
      • 선형대수학 (32)
      • 선형대수학(old) (0)
      • 프랑스어 (0)
      • 독서노트 (0)
      • 사진 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • bfs
  • 시뮬레이션
  • 코딩테스트
  • ps
  • github
  • 구현
  • It
  • 그리디
  • 백준
  • 개발
  • DevJoon
  • BOJ
  • 수학
  • 알고리즘
  • c++
  • 에세이
  • 브루트포스
  • Notion
  • stl
  • next_permutation
  • 선형대수학
  • Python
  • 백트래킹
  • dfs
  • DP
  • git bash

최근 댓글

최근 글

hELLO · Designed By 정상우.
Park Joonyoung
[골드 3] 2206번: 벽 부수고 이동하기
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.