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


문제

로봇 청소기가 있는 장소 N x M 은 빈칸(0) 또는 벽(1)으로 이뤄져있다. 일정한 규칙을 가지고 움직이는 로봇청소기를 이용할 때 청소한 영역의 개수를 구하는 문제이다.로봇청소기의 작동 규칙은 아래와 같다.

    1. 현재 위치를 청소한다.

    1. 현재 위치에서 현재 방향을 기준으로 왼쪽방향부터 차례대로 탐색을 진행한다.

      1) 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번 부터 진행한다. 2) 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다. 3) 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을​ 하고 2번으로 돌아간다. 4) 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.


접근방법

- 조건을 그래도 코드로 옮기면 된다. - 청소기의 방향인 북(0), 동(1), 남(2), 서(3) 에서 왼쪽을 보게되면 서(3), 북(0), 동(1), 남(2)을 바라보게 되는데, 이는 switch-case 구문보다 각 방향값에서 1을 빼주는 방법을 사용해 더 깔끔하게 코드를 짤 수 있다.(효근짱b) - 청소기가 네 방향을 모두 탐색한 것은 stay_time 이라는 변수를 두어 해결하였다.


소스코드

import java.util.Scanner;

public class Main{

   static int N;
   static int M;
   static int map[][];
   static int cur_dir;

   static class Pos{ int r; int c; }

   public static int changDir(int dir){
       return (dir == 0)? 3 : dir-1;
  }

   public static Pos changePos(int dir, Pos pos){
       Pos next_pos = new Pos();
       next_pos.r = pos.r;
       next_pos.c = pos.c;

       switch (dir){
           case 0: --next_pos.r; break;    // 북
           case 1: ++next_pos.c; break;    // 동
           case 2: ++next_pos.r; break;    // 남
           case 3: --next_pos.c; break;    // 서
      }
       return next_pos;
  }

   public static Pos backPos(int dir, Pos pos){
       Pos next_pos = new Pos();
       next_pos.r = pos.r;
       next_pos.c = pos.c;

       switch (dir){
           case 0: ++next_pos.r; break;    // 북
           case 1: --next_pos.c; break;    // 동
           case 2: --next_pos.r; break;    // 남
           case 3: ++next_pos.c; break;    // 서
      }
       return next_pos;
  }

   public static int cleaning(int map[][], int N, int M, Pos start){
       int result = 0;

       Pos cur_pos = new Pos();
       Pos before_pos = new Pos();
       cur_pos.c = before_pos.c = start.c;
       cur_pos.r = before_pos.r = start.r;

       int stay_time = 0;
       while(true){
           // 1. 현재 위치를 청소한다.
           if(map[cur_pos.r][cur_pos.c] == 0){
               map[cur_pos.r][cur_pos.c] = 2;
               ++result;
               //printarr(map);
          }

           // 2. 현재 위치에서 현재방향을 기준으로 왼쪽부터 탐색을 진행한다.
           cur_dir = changDir(cur_dir);
           Pos search_pos = changePos(cur_dir, cur_pos);
           ++stay_time;

           // 2-1. 왼쪽방향에 아직 청소하지 않은 공간이 있다면 청소
           if(map[search_pos.r][search_pos.c] == 0){
               cur_pos.r = search_pos.r;   // 현재 위치 변경
               cur_pos.c = search_pos.c;

               stay_time = 0;          // stay time 초기화
          }

           if(stay_time == 4){
               search_pos = backPos(cur_dir, cur_pos);
               // 뒤쪽이 벽이면
               if(map[search_pos.r][search_pos.c] == 1){
                   break;
              }else{
                   // 2-3. 후진
                   cur_pos.r = search_pos.r;
                   cur_pos.c = search_pos.c;
                   stay_time = 0;
              }
          }
      }

       return result;
  }

   private static void printarr(int arr[][]){
       System.out.println();
       for(int i=1; i<arr.length-1; i++){
           for(int j=1; j<arr[0].length-1; j++)
               System.out.print(map[i][j] + " ");
           System.out.println();
      }
  }

   public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);
       N = sc.nextInt();
       M = sc.nextInt();

       map = new int[N+2][M+2];
       for(int i=0; i<N+2; i++)
           for(int j=0; j<M+2; j++)
               map[i][j] = 1;

       Pos start = new Pos();
       start.r = sc.nextInt() + 1;
       start.c = sc.nextInt() + 1;
       cur_dir = sc.nextInt();

       for(int i=1; i<=N; i++)
           for(int j=1; j<=M; j++)
               map[i][j] = sc.nextInt();

       int result = cleaning(map, N, M, start);
       System.out.println(result);
  }
}


'알고리즘' 카테고리의 다른 글

백준15684 : 사다리 조작  (0) 2018.11.21
백준14889 : 스타트와 링크  (0) 2018.11.16
[JAVA] 백준 3055 : 탈출  (0) 2018.09.27
[JAVA] 백준 11559 : 뿌요뿌요  (0) 2018.09.20
[JAVA] 백준 3190 : 뱀  (1) 2018.09.18

+ Recent posts