ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준]14503: 로봇 청소기 - JAVA
    문제풀이/백준 2021. 2. 10. 16:32

    [백준]14503: 로봇 청소기 - JAVA

    www.acmicpc.net/problem/14503

     

    14503번: 로봇 청소기

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

    www.acmicpc.net

    풀이

    조건에 맞는 모든 경우를 탐색해야 하므로 dfs를 사용하여 풀었다. 

     

    여기서 중요한 조건은 탐색을 할 때에는 이전으로 되돌아 갈 수 없다는 조건이다. 

    예를들어서 아래와 같은 경우이고 시작 위치가 1,1일때

    1 0 0
    1 0 1
    1 0 0

    dfs로 탐색을 한 방향으로 하고 나면 아래와 같아진다.

    1 2 2
    1 2 1
    1 0 0

    이후에는 원래 dfs라면 1,1로 돌아와 탐색을 안한 부분을 탐색해 줄 것이다.

    그러나 이 문제에서는 탐색 중에서는 되돌아와서 다시 탐색을 진행할 수 없고, 더 이상 갈 수 없어 후진할 때만 이전의 노드를 재 방문할 수 있다.

    2 2
    1 2 1
    1 0 0

    그러므로 현재 노드가 0,2일때 더 이상 갈 수 있는 방향이 없으므로 후진을 한다. 이전 노드로 이동한다.

    1 2 2
    1 2 1
    1 0 0

    후진한 노드인 0,1일때 4방향 모두 청소가 되어있고 후진할 수 있는 방향은 1이므로 작동을 멈춰야 한다.

     

    코드

    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
    import java.util.*;
     
    public class Main {    
        
        static int n, m, r, c, d;
        static int[][] board;
        static int count = 1//시작 지점은 항상 청소한다.
        static int[] dx = {-1010}; //북, 동, 남, 서 순서대로
        static int[] dy = {010-1};
        
        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
            
            n = scan.nextInt();
            m = scan.nextInt();
            r = scan.nextInt();
            c = scan.nextInt();
            d = scan.nextInt();
            
            board = new int[n][m];
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < m; j++) {
                    board[i][j] = scan.nextInt();
                }
            }
            
            dfs(r, c, d);
            System.out.println(count);
        }    
        
        public static void dfs(int x, int y, int dir) {
            board[x][y] = 2//청소 했다는 의미
            
            for(int i = 0; i < 4; i++) {
                dir -= 1//왼쪽 방향으로 돌면서 탐색
                if(dir == -1) dir = 3;
                
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if(nx >= 0 && ny >= 0 && nx < n && ny < m) {
                    if(board[nx][ny] == 0) { //벽도 아니고 이미 청소한 곳도 아니라면 청소하러 이동한다
                        count++;
                        dfs(nx, ny, dir);
                        //일반적인 dfs는 가다가 길이 막히면 다시 되돌아와서 해당 위치부터 계산하지만, 이 문제는 후진할 때만 이전 길을 되돌가 가며 확인할 수 있으므로 return을 해서 다시 되돌아 와도 더 이상 움직이면 안된다.
                        return;
                    }
                }
            }
            
            //반목문을 빠져 나왔단는 것은 주변에 더 이상 청소할 공간이 없다는 의미이다.
            int d = (dir + 2) % 4//반대 방향으로 후진하기 위함.
            int bx = x + dx[d];//후진
            int by = y + dy[d];//후진
            if(bx >= 0 && by >= 0 && bx < n && by < m && board[bx][by] != 1) {
                dfs(bx, by, dir); //후진할 때 방향을 유지해야 한다.
            }
        }
    }
    cs

    댓글

Designed by Tistory.