[BaekJoon] 13459 구슬 탈출 (Java)

오태호·2023년 6월 21일
0

백준 알고리즘

목록 보기
256/395
post-thumbnail

1.  문제 링크

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

2.  문제




3.  소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    static int N, M;
    static char[][] board;
    static int[] hole;
    static Turn init;

    static void input() {
        Reader scanner = new Reader();

        N = scanner.nextInt();
        M = scanner.nextInt();
        board = new char[N][M];

        int[] red = null, blue = null;

        for(int row = 0; row < N; row++) {
            String info = scanner.nextLine();
            for(int col = 0; col < M; col++) {
                board[row][col] = info.charAt(col);

                if(board[row][col] == 'B') {
                    blue = new int[] {row, col};
                    board[row][col] = '.';
                }
                else if(board[row][col] == 'R') {
                    red = new int[] {row, col};
                    board[row][col] = '.';
                }
                else if(board[row][col] == 'O')
                    hole = new int[] {row, col};
            }
        }

        init = new Turn(red, blue, 0);
    }

    static void solution() {
        System.out.println(bfs(init));
    }

    static int bfs(Turn init) {
        Queue<Turn> queue = new LinkedList<>();
        boolean[][][][] visited = new boolean[N][M][N][M];

        queue.offer(init);
        visited[init.red[0]][init.red[1]][init.blue[0]][init.blue[1]] = true;

        while(!queue.isEmpty()) {
            Turn cur = queue.poll();

            if(board[cur.red[0]][cur.red[1]] == 'O' && board[cur.blue[0]][cur.blue[1]] != 'O')
                return 1;
            else if(board[cur.blue[0]][cur.blue[1]] == 'O') continue;

            int[] red = cur.red, blue = cur.blue;
            for(int dir = 0; dir < 4; dir++) {
                int[] tempRed = null, tempBlue = null;

                if(dir == 0) {
                    tempRed = moveLeft(red);
                    tempBlue = moveLeft(blue);

                    if(board[tempRed[0]][tempRed[1]] == 'O' && board[tempBlue[0]][tempBlue[1]] == 'O')
                        continue;
                    if(tempRed[0] == tempBlue[0] && tempRed[1] == tempBlue[1]) {
                        if(red[1] > blue[1]) tempRed[1]++;
                        else tempBlue[1]++;
                    }
                } else if(dir == 1) {
                    tempRed = moveRight(red);
                    tempBlue = moveRight(blue);

                    if(board[tempRed[0]][tempRed[1]] == 'O' && board[tempBlue[0]][tempBlue[1]] == 'O')
                        continue;
                    if(tempRed[0] == tempBlue[0] && tempRed[1] == tempBlue[1]) {
                        if(red[1] > blue[1]) tempBlue[1]--;
                        else tempRed[1]--;
                    }
                } else if(dir == 2) {
                    tempRed = moveUp(red);
                    tempBlue = moveUp(blue);

                    if(board[tempRed[0]][tempRed[1]] == 'O' && board[tempBlue[0]][tempBlue[1]] == 'O')
                        continue;
                    if(tempRed[0] == tempBlue[0] && tempRed[1] == tempBlue[1]) {
                        if(red[0] > blue[0]) tempRed[0]++;
                        else tempBlue[0]++;
                    }
                } else if(dir == 3) {
                    tempRed = moveDown(red);
                    tempBlue = moveDown(blue);

                    if(board[tempRed[0]][tempRed[1]] == 'O' && board[tempBlue[0]][tempBlue[1]] == 'O')
                        continue;
                    if(tempRed[0] == tempBlue[0] && tempRed[1] == tempBlue[1]) {
                        if(red[0] > blue[0]) tempBlue[0]--;
                        else tempRed[0]--;
                    }
                }

                if(visited[tempRed[0]][tempRed[1]][tempBlue[0]][tempBlue[1]]) continue;
                if(cur.moveNum + 1 > 10) continue;

                visited[tempRed[0]][tempRed[1]][tempBlue[0]][tempBlue[1]] = true;
                queue.offer(new Turn(tempRed, tempBlue, cur.moveNum + 1));
            }
        }

        return 0;
    }

    static int[] moveLeft(int[] loc) {
        for(int col = loc[1]; col >= 0; col--) {
            if(board[loc[0]][col] == 'O') return new int[] {loc[0], col};
            if(board[loc[0]][col] == '#') return new int[] {loc[0], col + 1};
        }

        return new int[] {loc[0], 0};
    }

    static int[] moveRight(int[] loc) {
        for(int col = loc[1]; col < M; col++) {
            if(board[loc[0]][col] == 'O') return new int[] {loc[0], col};
            else if(board[loc[0]][col] == '#') return new int[] {loc[0], col - 1};
        }

        return new int[] {loc[0], M - 1};
    }

    static int[] moveUp(int[] loc) {
        for(int row = loc[0]; row >= 0; row--) {
            if(board[row][loc[1]] == 'O') return new int[] {row, loc[1]};
            if(board[row][loc[1]] == '#') return new int[] {row + 1, loc[1]};
        }

        return new int[] {0, loc[1]};
    }

    static int[] moveDown(int[] loc) {
        for(int row = loc[0]; row < N; row++) {
            if(board[row][loc[1]] == 'O') return new int[] {row, loc[1]};
            if(board[row][loc[1]] == '#') return new int[] {row - 1, loc[1]};
        }

        return new int[] {N - 1, loc[1]};
    }

    static class Turn {
        int[] red, blue;
        int moveNum;

        public Turn(int[] red, int[] blue, int moveNum) {
            this.red = red;
            this.blue = blue;
            this.moveNum = moveNum;
        }
    }

    public static void main(String[] args) {
        input();
        solution();
    }

    static class Reader {
        BufferedReader br;
        StringTokenizer st;

        public Reader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while(st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return str;
        }
    }
}
profile
자바, 웹 개발을 열심히 공부하고 있습니다!

0개의 댓글