알고리즘/백준

[백준] 벽 부수고 이동하기 자바(Java) 풀이 및 해설

승민아 2024. 5. 22. 14:31

 

https://www.acmicpc.net/source/78677494

풀이 방법

[i][j] 위치에서 벽을 부순 상태인지 아닌지를 구분할 수 있게 3차원 배열을 이용해 푼다.

[i][j][0] 이라면 i,j 위치에 있을때 이전까지 벽을 한번도 부수지 않은 상태이고

[i][j][1] 이라면 i,j 위치에 있을때 이전에 벽을 부순 이력이 있는 상태이다.

 

[i][j][0]에서 다음 좌표에 벽을 만났다면 이 벽을 부술 수 있는 상태이다.

[i][j][1]이라면 다음 좌표에 벽이 있다면 이전에 벽을 부순 상태이기 때문이 벽을 부술 수 없다.

 

위의 3차원 배열을 이용해 BFS를 이용해 푼다.

 

전체 코드

import java.io.*;
import java.util.*;
public class Main {
    
    static class Pos {
        int y;
        int x;
        int z;
        int cnt;
        
        Pos(int y, int x, int z, int cnt) {
            this.y = y;
            this.x = x;
            this.z = z;
            this.cnt = cnt;
        }
    }
    
    public static void main(String[] args) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        String str = reader.readLine();
        String[] nm = str.split(" ");
        int n = Integer.parseInt(nm[0]);
        int m = Integer.parseInt(nm[1]);
        int[][] map = new int[n][m];
        for(int i=0; i<n; i++) {
            String input = reader.readLine();
            for(int j=0; j<m; j++) {
                map[i][j] = input.charAt(j) - '0';
            }
        }
        int[][][] arr = new int[n][m][2];
        for(int i=0; i<n; i++) {
            for(int j=0; j<m; j++) {
                Arrays.fill(arr[i][j], 987654321);
            }
        }
        
        Queue<Pos> q = new LinkedList<>();
        q.offer(new Pos(0, 0, 0, 1));
        arr[0][0][0] = 1;
        
        while(q.size() != 0) {
            Pos pos = q.poll();
            int y = pos.y;
            int x = pos.x;
            int z = pos.z;
            int cnt = pos.cnt;
            int[][] dir = {{-1,0}, {1,0}, {0,-1}, {0,1}};
            for(int i=0; i<4; i++) {
                int ny = y + dir[i][0];
                int nx = x + dir[i][1];
                
                if(ny>=0 && ny<n && nx>=0 && nx<m) {
                    
                    if(map[ny][nx] == 1 && z == 0 && cnt+1 < arr[ny][nx][1]) {
                        arr[ny][nx][1] = cnt+1;
                        q.offer(new Pos(ny, nx, 1, cnt+1));
                    }
                    if (map[ny][nx] == 0 && cnt+1 < arr[ny][nx][z]) {
                        arr[ny][nx][z] = cnt+1;
                        q.offer(new Pos(ny, nx, z, cnt+1));
                    }
                }
                
            }
            
        }
        
        if(arr[n-1][m-1][0] == 987654321 && arr[n-1][m-1][1] == 987654321) {
            System.out.println(-1);
        } else {
            System.out.println(Math.min(arr[n-1][m-1][0], arr[n-1][m-1][1]));
        }
    }
}