[BOJ] 17836: 공주님을 구해라! (JAVA)

2024. 3. 20. 14:16·Algorithm/BFS & DFS

문제

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

 

여담

예전에 BFS 문제를 풀 때, "탐색 도중에 상태가 변하는 것이 있다면 3차원 배열로 방문 처리를 진행하자!"라는 것을 외웠다. 그래서 빠르게 아이디어를 떠올릴 수 있었다. 역시 코테는 많은 유형을 접해보고 푸는 게 답인 듯하다. 많이 풀어보자!

 

풀이

용사가 (1, 1)에서 (N, M)까지 상하좌우로 이동하여 공주에게 도달할 수 있는 최단 시간을 구하는 것이므로, BFS 탐색을 수행하면 된다.

 

이때, 그람을 획득하면 성 내부의 벽을 부술 수 있다. 부술 수 있는 벽의 개수는 제한이 없으므로, 그람을 획득한다는 것은 벽이 없어진다는 것이랑 동일한 의미를 가진다. 

 

따라서 그람을 획득하지 못한 경우와 그람을 획득한 경우의 2가지로 나누어서 방문 처리를 진행하면 된다. 이렇게 탐색 도중에 상태가 변하는 것이 있다면 3차원 배열을 사용해서 방문 처리를 수행하면 된다.

  • visited[i][j][0]
    • 그람을 획득하지 못한 경우
  • visited[i][j][1]
    • 그람을 획득한 경우

 

자세한 내용은 코드를 참고하면 된다.

 

코드

import java.io.*;
import java.util.*;

public class Main {
    static int N, M, T;
    static int[][] castle;
    static boolean[][][] visited;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        T = Integer.parseInt(st.nextToken());

        castle = new int[N][M];
        visited = new boolean[N][M][2]; // [i][j][0]: 그람 획득 X, [i][j][1]: 그람 획득 O
        Pos gram = null;
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < M; j++) {
                castle[i][j] = Integer.parseInt(st.nextToken());
                if (castle[i][j] == 2) {
                    gram = new Pos(i, j, 0,false);
                }
            }
        }

        int time = bfs(gram);
        System.out.println(time == -1 ? "Fail" : time);
    }

    public static int bfs(Pos gram) {
        Queue<Pos> queue = new LinkedList<>();
        queue.offer(new Pos(0, 0, 0, false));
        visited[0][0][0] = true;

        int time = -1;
        int[][] move = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
        while (!queue.isEmpty()) {
            Pos pos = queue.poll();
            if (pos.x == N - 1 && pos.y == M - 1) {
                if (pos.time <= T) time = pos.time;
                break;
            }

            // 현재 위치에 그람이 있는 경우, 그람을 획득함
            if (pos.x == gram.x && pos.y == gram.y) {
                pos.getGram = true;
                visited[pos.x][pos.y][1] = true;
            }

            // T 시간을 넘으면 구하지 못함
            if (pos.time > T) break;

            // 상하좌우로 이동
            for (int i = 0; i < 4; i++) {
                int nx = pos.x + move[i][0];
                int ny = pos.y + move[i][1];
                if (nx < 0 || ny < 0 || nx >= N || ny >= M) {
                    continue;
                }

                if (pos.getGram) { // 그람을 획득한 경우
                    // 벽이 있어도 상관없음
                    if (!visited[nx][ny][1]) {
                        queue.offer(new Pos(nx, ny, pos.time + 1, true));
                        visited[nx][ny][1] = true;
                    }

                } else { // 그람을 획득하지 못한 경우
                    // 벽이 있으면 지나가지 못함
                    if (!visited[nx][ny][0] && castle[nx][ny] != 1) {
                        queue.offer(new Pos(nx, ny, pos.time + 1, false));
                        visited[nx][ny][0] = true;
                    }
                }
            }
        }
        return time;
    }

    static class Pos {
        int x, y;
        int time;
        boolean getGram;

        public Pos(int x, int y, int time, boolean getGram) {
            this.x = x;
            this.y = y;
            this.time = time;
            this.getGram = getGram;
        }
    }
}

'Algorithm > BFS & DFS' 카테고리의 다른 글

[BOJ] 16932: 모양 만들기 (JAVA)  (1) 2024.04.26
[BOJ] 7569: 토마토 (JAVA)  (0) 2024.03.20
[BOJ] 7576: 토마토 (JAVA)  (0) 2024.03.20
[BOJ] 10026: 적록색약 (JAVA)  (0) 2024.03.20
[BOJ] 5427: 불 (JAVA)  (0) 2024.03.20
'Algorithm/BFS & DFS' 카테고리의 다른 글
  • [BOJ] 16932: 모양 만들기 (JAVA)
  • [BOJ] 7569: 토마토 (JAVA)
  • [BOJ] 7576: 토마토 (JAVA)
  • [BOJ] 10026: 적록색약 (JAVA)
hjin28
hjin28
  • hjin28
    끄적이는 기록장
    hjin28
  • 전체
    오늘
    어제
  • 블로그 메뉴

    • 홈
    • 태그
    • GitHub
    • 이전 블로그
    • 분류 전체보기
      • TIL
      • Frontend
      • Backend
      • Infra
      • Java
        • 이것이 자바다
      • CS
        • 컴퓨터구조
        • 운영체제
        • 네트워크
        • 데이터베이스
      • Algorithm
        • 자료구조
        • 시뮬레이션
        • 완전탐색
        • BFS & DFS
        • DP
        • 그리디
        • 최단경로
        • 유니온파인드
        • 위상정렬
        • 정렬
        • SQL
      • ETC
  • 최근 글

  • 태그

    백준
    자바
    덱
    다익스트라
    vue
    springsecurity
    다이나믹프로그래밍
    위상정렬
    DFS
    유니온파인드
    구현
    Programmers
    til
    JWT
    최단경로
    완전탐색
    java
    자료구조
    SWEA
    BFS
    컴퓨터구조
    ec2
    백트래킹
    websocket
    Spring
    비트마스킹
    DP
    투포인터
    SQL
    그리디
  • hELLO· Designed By정상우.v4.10.1
hjin28
[BOJ] 17836: 공주님을 구해라! (JAVA)
상단으로

티스토리툴바