💡Problem Solving/BOJ

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

gom20 2021. 12. 16. 19:58

문제

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

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어

www.acmicpc.net

 

풀이

dfs + 구현 문제이다. 

방문 체크를 하면서 로봇 청소기 작동 원리대로 코드를 구현하면 된다.

현재 방향에 따른 왼쪽 좌표와 후진 좌표, 회전 방향은 초반에 미리 정의 해두었다. 

(나중에 조건문으로 짜면 골치 아프당)

 

소스코드

package simulation;

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

public class BOJ14503 {
    static int[][] map;
    static boolean[][] visited;
    // 0 북, 1 동, 2, 남, 3, 서
    static int[] rotation = new int[]{3, 0, 1, 2};
    static int[][] leftMove = new int[][]{{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
    static int[][] backMove = new int[][]{{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
    static int N, M;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        st = new StringTokenizer(br.readLine());
        int x = Integer.parseInt(st.nextToken());
        int y = Integer.parseInt(st.nextToken());
        int dir = Integer.parseInt(st.nextToken());

        map = new int[N][M];
        visited = new boolean[N][M];
        for(int i = 0; i < N; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < M; j++){
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        // 1. 현재 위치를 청소한다.
        visited[x][y] = true;
        // 2. 현재 위치에서 현재 방향을 기준으로 왼쪽 방향부터 차례대로 인접한 칸을 탐색한다.
        dfs(x, y, dir);
    }

    public static void printAnswer(){
        int answer = 0;
        for(int i = 0; i < visited.length; i++){
            for(int j = 0; j < visited[i].length; j++){
                if(visited[i][j]) answer++;
            }
        }
        System.out.println(answer);
    }

    public static void dfs(int x, int y, int dir){

        // 네 방향 모두 청소가 되어있거나 벽인가?
        boolean isCompleted = true;
        for(int[] d : leftMove){
            int nx = x + d[0];
            int ny = y + d[1];
            if(isValid(nx, ny) && map[nx][ny] == 0 && !visited[nx][ny]){
                isCompleted = false;
            }
        }
        if(isCompleted) {
            int nx = x + backMove[dir][0];
            int ny = y + backMove[dir][1];
            // 네 방향 모두 청소가 이미 되어있거나 벽이면서,
            // 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
            if(isValid(nx, ny) && map[nx][ny] == 1){
                printAnswer();
                System.exit(0);
            }
            dfs(nx, ny, dir);
        }

        // 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면,
        // 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
        int nx = x + leftMove[dir][0];
        int ny = y + leftMove[dir][1];

        if(isValid(nx, ny) && map[nx][ny] == 0 && !visited[nx][ny]){
            visited[nx][ny] = true;
            dfs(nx, ny, rotation[dir]);
        } else {
            dfs(x, y, rotation[dir]);
        }
    }

    public static boolean isValid(int x, int y){
        if(x < 0 || y < 0 || x >= N || y >= M) return false;
        return true;
    }
}

'💡Problem Solving > BOJ' 카테고리의 다른 글

[BOJ 16236] 아기 상어 (Java)  (0) 2021.12.18
[BOJ 2468] 안전 영역 (Java)  (0) 2021.12.17
[BOJ 14501] 퇴사 (Java)  (0) 2021.12.15
[BOJ 2636] 치즈 (Java)  (0) 2021.12.13
[BOJ 4195] 친구 네트워크 (Java)  (0) 2021.12.12