티스토리 뷰

문제 - (https://www.acmicpc.net/problem/14503)

문제에서 주어진 로봇 청소기의 작동 방법대로 구현하면 되는 문제였다.

시뮬레이션 문제들은 문제를 먼저 이해하는 것이 중요한데, 나는 문제 하는데 시간이 좀 걸렸다ㅠㅠ

 

- 로봇 청소기 작동 순서 -

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

 

내 코드에 주석과 함께 적어놨으니 참고하면 된다.

코드를 보기 전에, 짚고 넘어가야할 부분이 있을 것 같아 설명하겠다.

    static int[] dx = {-1, 0, 1, 0}; // 북 동 남 서
    static int[] dy = {0, 1, 0, -1};
    static int[] dirLeft = {3, 0, 1, 2}; // 왼쪽
    static int[] dirBack = {2, 3, 0, 1}; // 후진

바로 이부분!

주석에 설명이 있지만 헷갈릴 수 있어 머릿속에 되새길 겸 설명하겠다.

문제에서 "방향 d가 주어진다. d가 0인 경우에는 북쪽을, 1인 경우에는 동쪽을, 2인 경우에는 남쪽을, 3인 경우에는 서쪽을 바라보고 있는 것"이라고 했다. 이것을 염두에 두고 아래 표를 보자.

변수명/d 0 (북) 1 (동) 2 (남) 3 (서)
dirLeft 3 0 1 2
dirBack 2 3 0 1

예를 들어서 이 표의 의미를 설명하자면

0(북) 일 때의 왼쪽은 3(서)이고, 뒤쪽은 2(남)이라는 뜻이다.

따라서 dirLeft에 현재 보고 있는 방향을 인덱스로 사용하면 현재 보고있는 방향에서 왼쪽은 어느 방향인지 알 수 있다.

로봇 청소기의 위치를 그 방향으로 이동시키면 끝!!!

int x = 현재 위치의 x좌표;
int y = 현재 위치의 y좌표;
int dir = 현재 보고있는 방향;

int left = dirLeft[dir];
int nx = x + dx[left];
int ny = y + dy[left];
        
int back = dirBack[dir];
int bx = x + dx[back];
int by = y + dy[back];

📌주의할 점

  • "현재 방향을 기준으로 왼쪽 방향부터"와 같이 헷갈릴 수 있는 부분은 정확히 하고 넘어가야 한다.

😅실수

  • 문제를 정확히 이해하고 코딩해나가자.. 대충 이해하고 시작하면 나중에 더 답 없어짐

 


코드

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

// 골드5 - 1사간 10분
public class RoboticVacuumCleaner {
    static int N;
    static int M;
    static int[][] map;
    static int rR;
    static int rC;
    static int rDir;
    static int[] dx = {-1, 0, 1, 0}; // 북 동 남 서
    static int[] dy = {0, 1, 0, -1};
    static int[] dirLeft = {3, 0, 1, 2}; // dirLeft[i] = i가 0,1,2,3 일 때 왼쪽이 되는 곳은 dx[i],dy[i]임
    static int[] dirBack = {2, 3, 0, 1}; // 후진
    static int answer = 0;

    static void recursion(int x, int y, int dir, int end) {
        /* 1 */
        // 현재 위치 청소
        if (map[x][y] == 0) {
            map[x][y] = 2;
            answer++;
            // print();
        }
        
        /* 2 */
        int currentLeft = dirLeft[dir];
        int nx = x + dx[currentLeft];
        int ny = y + dy[currentLeft];

        if (nx < 0 || ny < 0 || nx >= N || ny >= M) return;
        if (map[nx][ny] == 0) {
            /* 2-1 */
            // 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면,
            // 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
            recursion(nx, ny, currentLeft, 0);
        } else {
            // 왼쪽 방향에 청소할 공간이 없다면,
            if (end != 4) {
                /* 2-2 */
                // 그 방향으로 회전하고 2번으로 돌아간다.
                recursion(x, y, currentLeft, end + 1);
            } else {
                // 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는,
                int back = dirBack[dir];
                int bx = x + dx[back];
                int by = y + dy[back];

                if (bx < 0 || by < 0 || bx >= N || by >= M) return;
                if (map[bx][by] != 1)
                    /* 2-3 */
                    // 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
                    recursion(bx, by, dir, 0);
                else
                    /* 2-4 */
                    // 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
                    return;
            }
        }
    }

    static void print() {
        System.out.println("--------------------");
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        map = new int[N][M];

        st = new StringTokenizer(br.readLine());
        rR = Integer.parseInt(st.nextToken());
        rC = Integer.parseInt(st.nextToken());
        rDir = Integer.parseInt(st.nextToken());

        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());
            }
        }

        recursion(rR, rC, rDir, 0);
        System.out.println(answer);
    }
}

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
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
글 보관함