티스토리 뷰

더 깔끔한 노션을 원한다면

 

Baekjoon 14503 로봇 청소기 - Simulation

설계

www.notion.so

 

14503번: 로봇 청소기

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

www.acmicpc.net

설계

시뮬레이션은 문제에서 나와있는 설계를 그대로 구현하면 되는 문제이다.

1

현재 위치를 청소한다.

// 1. 현재 위치를 청소한다.
if (area[robotY][robotX] == NON_CLEAN) {
  answer++;
  area[robotY][robotX] = ALREADY_CLEAN;
}

2

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

int[] dx = { 0, 1, 0, -1 };
int[] dy = { -1, 0, 1, 0 };

...

for (int i = 0; i < 4; i++) {
  if (--presentRobotDirect < 0) {
    presentRobotDirect = 3;
  }
  int x = robotX;
  int y = robotY;
  x += dx[presentRobotDirect];
  y += dy[presentRobotDirect];
  // 2-1. 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
  if (area[y][x] == NON_CLEAN) {
    robotX = x;
    robotY = y;
    robotDirect = presentRobotDirect;
    flag = true;
    break;
  }
// 2-2. 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다. continue
}

왼쪽 방향부터 차례로 청소하지 않은 공간인지 확인해준다.

2-1

왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.

// 2-1
if (flag) {
  continue;
}

위에 2번에서 flag가 true로 바뀐다면 continue를 진행해준다.

2-2

왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.

2-2의 경우는 for문을 계속 진행해주면 된다.

2-3, 2-4

네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.

// 2-3. 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
int behindX = robotX + dx[(robotDirect + 2) % 4];
int behindY = robotY + dy[(robotDirect + 2) % 4];

// 2-4. 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
if (area[behindY][behindX] == WALL) {
  break;
}
robotX = behindX;
robotY = behindY;
robotDirect = presentRobotDirect;

현재 보고 있는 방향 기준으로 뒤에 좌표가 벽이라면 반복문을 종료시켜준다.

전체 코드

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

public class Main {
  public static void main(String[] args) throws Exception {
    Baekjoon solution = new Baekjoon();
    solution.P14503();
  }
}

class Baekjoon {
  int[][] area;
  final int NON_CLEAN = 0;
  final int WALL = 1;
  final int ALREADY_CLEAN = 2;
  int[] dx = { 0, 1, 0, -1 };
  int[] dy = { -1, 0, 1, 0 };

  public void P14503() throws Exception {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer(br.readLine());
    int answer = 0;
    int N = Integer.parseInt(st.nextToken());
    int M = Integer.parseInt(st.nextToken());
    area = new int[N][M];
    st = new StringTokenizer(br.readLine());
    int robotY = Integer.parseInt(st.nextToken());
    int robotX = Integer.parseInt(st.nextToken());
    int robotDirect = Integer.parseInt(st.nextToken());
    for (int i = 0; i < N; i++) {
      st = new StringTokenizer(br.readLine());
      for (int j = 0; j < M; j++) {
        area[i][j] = Integer.parseInt(st.nextToken());
      }
    }
    while (true) {
      // 1. 현재 위치를 청소한다.
      if (area[robotY][robotX] == NON_CLEAN) {
        answer++;
        area[robotY][robotX] = ALREADY_CLEAN;
      }
      int presentRobotDirect = robotDirect;
      boolean flag = false;
      // 2. 현재 위치에서 현재 방향을 기준으로 왼쪽방향부터 차례대로 탐색을 진행한다.
      for (int i = 0; i < 4; i++) {
        if (--presentRobotDirect < 0) {
          presentRobotDirect = 3;
        }
        int x = robotX;
        int y = robotY;
        x += dx[presentRobotDirect];
        y += dy[presentRobotDirect];
        // 2-1. 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
        if (area[y][x] == NON_CLEAN) {
          robotX = x;
          robotY = y;
          robotDirect = presentRobotDirect;
          flag = true;
          break;
        }
        // 2-2. 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다. continue
      }
      // 2-1
      if (flag) {
        continue;
      }
      // 2-3. 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
      int behindX = robotX + dx[(robotDirect + 2) % 4];
      int behindY = robotY + dy[(robotDirect + 2) % 4];

      // 2-4. 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
      if (area[behindY][behindX] == WALL) {
        break;
      }
      robotX = behindX;
      robotY = behindY;
      robotDirect = presentRobotDirect;
    }
    System.out.println(answer);
  }
}

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

Baekjoon 3190 뱀 - Deque  (0) 2020.10.23
Baekjoon 13459 구슬 탈출 - BFS  (0) 2020.10.22
Baekjoon 1987 알파벳 - BackTracking  (0) 2020.10.20
Baekjoon 1759 암호 만들기 - BackTracking  (0) 2020.10.20
Baekjoon 9012 괄호 - Stack  (0) 2020.10.13
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함