[백준/BOJ] 2206 벽 부수고 이동하기 - JAVA

2025. 6. 8. 17:45·알고리즘/문제풀이

[백준/BOJ] 2206 벽 부수고 이동하기 - JAVA

문제

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

 

문제 분석

조건

N×M 크기의 맵이 있다. 0은 이동할 수 있는 곳이고, 1은 벽이 있는 곳이다.

`1, 1`위치에서 `N, M`위치까지 이동하는데, 최단 경로로 이동하려 한다. 이동 중 1개의 벽을 부수고 이동할 수 있을 때 최단 이동 횟수를 구하는 문제이다. 이동이 불가능할 경우 `-1`출력

풀이방법

기본적인 BFS를 활용한 최단경로 구하는 문제에서 벽을 1번 부술수있는부술수 있는 경우가 추가된 형태이다. 각 칸에 이동했을 때, 벽을 부술 수 있는 횟수를 포함하여 `visited`를 관리하면 되는 문제이다. `Queue`에 넣는 좌표값에도 벽을 부술수 있는 횟수를 관리하기 위해 `Node`를 정의하여 관리해 주었다.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

class Node {
    int r;
    int c;
    int boom;   // 부수기 가능 횟수
    int count;  // 이동 수

    public Node(int r, int c, int boom, int count) {
        this.r = r;
        this.c = c;
        this.boom = boom;
        this.count = count;
    }
}

public class Main {
    static int N, M;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        // 지도 입력
        char[][] map = new char[N + 1][M + 1];
        for (int r = 1; r <= N; r++) {
            String line = br.readLine();
            for (int c = 1; c <= M; c++) {
                map[r][c] = line.charAt(c - 1);
            }
        }
        System.out.println(bfs(map));
    }

    private static int bfs(char[][] map) {
        // 벽 부수기 가능 횟수를 포함하여 3차원 배열로 방문 표시
        boolean[][][] visited = new boolean[N + 1][M + 1][2];
        int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
        visited[1][1][1] = true;
        Queue<Node> queue = new ArrayDeque<>();
        queue.add(new Node(1, 1, 1, 1));
        while (!queue.isEmpty()) {
            Node now = queue.poll();
            if (now.r == N && now.c == M) {
                // 목표좌표 도달
                return now.count;
            }
            for (int[] dir : dirs) {
                int nextR = now.r + dir[0];
                int nextC = now.c + dir[1];
                if (nextR == 0 || nextC == 0 || nextR > N || nextC > M) {
                    continue;
                }
                if (map[nextR][nextC] == '1') {// 벽이면
                    if (now.boom == 1 && !visited[nextR][nextC][0]) {// 부수기 가능
                        visited[nextR][nextC][0] = true;
                        queue.add(new Node(nextR, nextC, 0, now.count + 1));
                    }
                } else {
                    if (!visited[nextR][nextC][now.boom]) {
                        visited[nextR][nextC][now.boom] = true;
                        queue.add(new Node(nextR, nextC, now.boom, now.count + 1));
                    }
                }
            }
        }
        return -1;
    }
}

 

728x90
저작자표시 비영리 변경금지 (새창열림)
'알고리즘/문제풀이' 카테고리의 다른 글
  • [백준/BOJ] 19237 어른 상어 - JAVA
  • [프로그래머스] 12929 올바른 괄호의 갯수 - JAVA (카탈란 수)
  • [백준/BOJ] 19236 청소년 상어 - JAVA
  • [프로그래머스] 42628 이중우선순위큐 - JAVA
LIRI
LIRI
  • LIRI
    기록
    LIRI
  • 전체
    오늘
    어제
    • 분류 전체보기 (74)
      • 블로그 꾸미기 (0)
      • Spring (6)
      • 바이브코딩 (1)
      • React (3)
      • CS (0)
      • 알고리즘 (57)
        • 개념 (2)
        • 문제풀이 (54)
      • Java (1)
      • DB (1)
      • log (4)
        • SSAFY (3)
        • 궁금 (1)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 공지사항

  • 인기 글

  • 태그

    JWT
    느좋코딩
    Spring
    Java
    그리디
    BFS
    Security
    리액트
    커서ai
    LV2
    바이브코딩
    싸피
    알고리즘 문제풀이
    Springsecurity
    알고리즘
    최장증가부분수열
    프로그래머스
    dfs
    BOJ
    ssafy 합격 후기
    springboot
    백준
    SSAFY 9기
    비트마스킹
    pccp모의고사
    lv3
    SSAFY
    LIS
    너비우선탐색
    dp
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
LIRI
[백준/BOJ] 2206 벽 부수고 이동하기 - JAVA
상단으로

티스토리툴바