[BaekJoon] 14503 로봇 청소기 (Java)

오태호·2024년 3월 18일
0

백준 알고리즘

목록 보기
387/395
post-thumbnail

1.  문제 링크

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

2.  문제


3.  소스코드

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

public class Main {
    static int[] dx = {-1, 0, 1, 0};
    static int[] dy = {0, -1, 0, 1};
    static int[][] directionAmounts = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};

    static int answer;
    static int rowSize;
    static int colSize;
    static int direction; // 0 : 북, 1 : 동, 2 : 남, 3 : 서
    static int[] robot;
    static int[][] map; // 0 : 청소되지 않은 빈 칸, 1 : 벽

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

        rowSize = scanner.nextInt();
        colSize = scanner.nextInt();

        int x = scanner.nextInt();
        int y = scanner.nextInt();
        robot = new int[]{x, y};

        direction = scanner.nextInt();

        map = new int[rowSize][colSize];
        for (int row = 0; row < rowSize; row++) {
            for (int col = 0; col < colSize; col++) {
                map[row][col] = scanner.nextInt();
            }
        }
    }

    /*
     * 구현 문제이기 때문에 주어진 조건을 그대로 구현하면 된다
     *
     * 1. 현재 로봇의 위치가 아직 청소되지 않은 칸이라면 이를 청소하고 청소했음을 표시하기 위해 값을 0에서 -1로 변경한다
     * 2. 로봇 주변 4칸 중 청소되지 않은 빈 칸이 있는지 확인한다
     *      a. 로봇 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우
     *          - 로봇을 반시계 방향으로 90도 회전시킨다
     *              - 문제 조건에서 방향을 나타내는 값이 시계방향으로 1씩 증가하기 때문에
     *                현재 바라보고 있는 방향에서 3을 더한 값을 4로 나눈 나머지값이 반시계 방향으로 회전한 방향의 값이다
     *              - 반시계 방향으로 회전한 방향 앞쪽 칸을 바라보고 만약 청소되지 않은 빈 칸인 경우 해당 칸으로 이동시킨다
     *      b. 로봇 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우
     *          - 현재 바라보고 있는 방향의 반대 방향을 구한다
     *              - 문제 조건에서 방향을 나타내는 값이 시계방향으로 1씩 증가하기 때문에
     *                현재 바라보고 있는 방향에서 2를 더한 값을 4로 나눈 나머지값이 반대 방향으로 회전한 방향의 값이다
     *          - 반대 방향으로 회전한 방향 앞쪽 칸을 바라보고 만약 청소되지 않은 빈 칸이라면 해당 칸으로 이동시킨다
     *          - 청소되지 않은 빈 칸이 아니라면 로봇 청소기의 이동이 끝났음을 알리기 위해 false를 반환한다
     */
    static void solution() {
        while (true) {
            if (!turn()) {
                break;
            }
        }

        System.out.println(answer);
    }

    static boolean turn() {
        if (map[robot[0]][robot[1]] == 0) {
            map[robot[0]][robot[1]] = -1;
            answer++;
        }

        if (hasNonCleanedSpace(robot)) {
            goForward();
        } else {
            if (!goBack()) {
                return false;
            }
        }

        return true;
    }

    static void goForward() {
        direction = (direction + 3) % 4;
        int cx = robot[0] + directionAmounts[direction][0];
        int cy = robot[1] + directionAmounts[direction][1];

        if (isInMap(cx, cy) && map[cx][cy] == 0) {
            robot = new int[]{cx, cy};
        }
    }

    static boolean goBack() {
        int dir = (direction + 2) % 4;
        int cx = robot[0] + directionAmounts[dir][0];
        int cy = robot[1] + directionAmounts[dir][1];

        if (isInMap(cx, cy) && map[cx][cy] != 1) {
            robot = new int[]{cx, cy};
            return true;
        } else {
            return false;
        }
    }

    static boolean hasNonCleanedSpace(int[] robot) {
        for (int dir = 0; dir < dx.length; dir++) {
            int cx = robot[0] + dx[dir];
            int cy = robot[1] + dy[dir];

            if (isInMap(cx, cy) && map[cx][cy] == 0) {
                return true;
            }
        }

        return false;
    }

    static boolean isInMap(int x, int y) {
        return x >= 0 && x < rowSize && y >= 0 && y < colSize;
    }

    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());
        }
    }
}
profile
자바, 웹 개발을 열심히 공부하고 있습니다!

0개의 댓글