ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준]20926: 얼음 미로 - JAVA
    문제풀이/백준 2021. 7. 23. 17:23

    [백준]20926: 얼음 미로

    풀이

    🪑 구현 + 다익스트라 문제이다. 

     

     

    📝문제의 조건을 정리해보자.

    • 얼음 미로에서는 한 방향으로 이동시 바위나 출구를 만날때 까지 멈출 수 없다. 바깥은 절벽이다.
    • T: 상하좌우로 이동할 수 있다.
    • R: 통과할 수 없으며 부딪히면 멈춘다
    • H: 이곳에 빠지면 탈출할 수 없다.
    • E: 미로를 탈출하는 유일한 출구이다.
    • 각 위치마다 미끌시간이 존재하며 탈출할 수 있는 최단 미끌시간을 구한다.

     

     

    🔧 다음과 같은 풀이를 생각해 주었다.

    1. 다익스트라를 사용한다.
    2. 한번 이동할 때 해당 방향으로 이동할 수 있는지 먼저 확인한다.
    3. 이동 가능하면 그 방향으로 갈 수 있는 곳까지 간다.
    4. 도착한 후 더 짧은 미끌시간을 계산해 준다.
    5. 도착 노드의 최단 미끌시간을 출력한다.

     

    📌 처음엔 70 ~ 80프로 쯤에 틀렸었는데, INF 값을 Integer.MAX_VALUE로 변경해주니 통과되었다.

     

     

    🔹 다익스트라를 사용한다.

    - 최단 거리가 아닌, 최단 미끌시간을 갖는 경로를 계산해 주어야 하므로 단순 BFS로는 풀 수 없다. 다익스트라 알고리즘으로 최단 미끌시간을 저장해 주면서 탐색해 주어야 한다.

    - 출발 지점인 T에서 시작하여 모든 노드로 가는 최단 경로를 탐색한다.

    - 더 짧은 미끌시간을 가지는 순서대로 탐색을 한다.

     

    🔹 한번 이동할 때 해당 방향으로 이동할 수 있는지 먼저 확인한다.

    - 단순히 이동만 하는 것이 아니라 이동 하면서 이동 경로에 있는 값이 탐색에 필요하다. 

    - 그러므로 일단 해당 방향으로 갈 수 있는지 먼저 확인 후, 갈 수 있을때만 경로에 있는 값을 계산해 준다.

     

    🔹 이동 가능하면 그 방향으로 갈 수 잇는 곳까지 간다.

    - 그 방향으로 갈 수 있는지 확인하기 위해 현재 위치에서 이동하는 방향으로의 비율을 늘려주며 탐색하였다.

    - 가는 동안에 맵의 범위를 벗어나거나, H를 만난다면 갈 수 없는 방향이다.

    - 가는 길에 바위를 만나면 그 전까지만 이동 가능한 위치가 된다.

    - 가는 길에 출구를 만나면 출구까지 이동 가능한 위치가 된다.

     

    🔹도착한 후 더 짧은 미끌시간을 계산해 준다.

    - 원래의 미끌시간이랑 비교를 해서 현재 경로까지 이동하는 동안 추가되는 미끌시간과 지금까지 이동하며 추가된 미끌시간의 합 중에 더 작은 값을 저장해 준다.

     

    🔹 도착 노드의 최단 미끌시간을 출력한다.

    - 탐색할 수 있는 모든 경우가 끝나면 도착 노드의 최단 미끌시간을 출력해 준다.

     

    코드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    import java.util.*;
     
    public class Main {
     
        static char[][] board;
        static int[][] dist;
        static int w, h;
        static int[] dx = {010-1};
        static int[] dy = {-1010};
     
        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
     
            //입력
            w = scan.nextInt();
            h = scan.nextInt();
            scan.nextLine();
     
            board = new char[h][w];
            int start_x = -1, start_y = -1;
            int end_x = -1, end_y = -1;
            for(int i = 0; i < h; i++) {
                String str = scan.nextLine();
                for(int j = 0; j < w; j++) {
                    board[i][j] = str.charAt(j);
                    if(board[i][j] == 'T') {
                        start_x = i;
                        start_y = j;
                    } else if(board[i][j] == 'E') {
                        end_x = i;
                        end_y = j;
                    }
                }
            }
            //입력 끝
     
            int INF = Integer.MAX_VALUE;
            dist = new int[h][w];
            for(int i = 0; i < h; i++) {
                Arrays.fill(dist[i], INF);
            }
     
            bfs(start_x, start_y);
            if(dist[end_x][end_y] == INF) System.out.println("-1");
            else System.out.println(dist[end_x][end_y]);
        }   
     
        public static void bfs(int x, int y) {
            PriorityQueue<Node> q = new PriorityQueue<>();
            boolean[][] visited = new boolean[h][w];
            q.offer(new Node(x, y, 0));
            dist[x][y] = 0;
     
            while(!q.isEmpty()) {
                Node current = q.poll();
            
                if(visited[current.x][current.y]) continue;
                visited[current.x][current.y] = true;
     
                for(int i = 0; i < 4; i++) {
                    int go_ratio = can_go(i, current.x, current.y);
                    if(go_ratio < 1continue;
     
                    int sum_dist = 0;
                    for(int j = 1; j <= go_ratio; j++) {
                        if(board[current.x + dx[i] * j][current.y + dy[i] * j] == 'E') continue;
                        else sum_dist += (board[current.x + dx[i] * j][current.y + dy[i] * j] - '0');
                    }
                    int nx = current.x + dx[i] * go_ratio;
                    int ny = current.y + dy[i] * go_ratio;
     
                    if(dist[nx][ny] > sum_dist + current.time) {
                        dist[nx][ny] = sum_dist + current.time;
                        q.offer(new Node(nx, ny, dist[nx][ny]));
                    }
                }
            }
        }
     
        public static int can_go(int dir, int x, int y) {
            int ratio = 1;
            while(true) {
                int nx = x + dx[dir] * ratio;
                int ny = y + dy[dir] * ratio;
     
                if(nx < 0 || ny < 0 || nx >= h || ny >= w) break;
                if(board[nx][ny] == 'H'break;
                
                if(board[nx][ny] == 'R'return ratio - 1;
                if(board[nx][ny] == 'E' ) return ratio;
     
                ratio++;
            }
            return -1;
        }
     
        public static class Node implements Comparable<Node>{
            int x;
            int y;
            int time;
     
            public Node(int x, int y, int time) {
                this.x = x;
                this.y = y;
                this.time = time;
            }
     
            @Override
            public int compareTo(Node n) {
                return this.time - n.time;
            }
        }
    }
    cs

    댓글

Designed by Tistory.