KwanIk Devlog

1. 문제

 

14503번: 로봇 청소기

첫째 줄에 방의 크기 $N$과 $M$이 입력된다. $(3 \le N, M \le 50)$  둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 $(r, c)$와 처음에 로봇 청소기가 바라보는 방향 $d$가 입력된다. $d$가 $0$인 경우 북쪽

www.acmicpc.net

 

 

2. 풀이

단순한 구현 문제이지만, 로봇의 동작이 다소 복잡하게 정의되어 있어 난이도가 올라간 것으로 보인다. 하지만 문제에서 정의한 청소기의 동작 방식을 순차적으로 잘 구현만 한다면, 큰 어려움은 없다.

 

  1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
  2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
    1. 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
    2. 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
  3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
    1. 반시계 방향으로 90º 회전한다.
    2. 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
    3. 1번으로 돌아간다.

 

필자의 경우 시작 위치와 방향을 갖고 있는 Robot 객체를 생성해, Robot이 스스로 동작하고 움직이도록 처리하였다.

 

3. 소스코드

더보기
public class sml_14503_robotVacuum {
    static final int[] dy = {-1, 0, 1, 0};
    static final int[] dx = {0, 1, 0, -1};

    static int N, M;
    static int[][] map;
    static boolean[][] cleaned;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        st = new StringTokenizer(br.readLine());
        Robot robot = new Robot(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));

        map = new int[N][M];
        cleaned = 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());
            }
        }

        robot.activate();

        bw.write(robot.getCleanedCnt() + "");
        bw.close();
        br.close();
    }

    static boolean isOutOfRange(int y, int x) {
        return y < 0 || x < 0 || N <= y || M <= x || map[y][x] == 1;
    }

    static class Robot {
        int y, x, dir;
        int cleanedCnt = 0;

        public Robot(int y, int x, int dir) {
            this.y = y;
            this.x = x;
            this.dir = dir;
        }

        public int getCleanedCnt() {
            return cleanedCnt;
        }

        // 청소기 동작시키기
        void activate() {
            while (true) {
                // 1번 동작 - 청소되지 않은 경우, 현재 칸을 청소한다.
                if (!cleaned[y][x] && map[y][x] == 0) {
                    cleanedCnt++;
                    cleaned[y][x] = true;
                }

                int ny = y;
                int nx = x;
                
                // 3번 동작 - 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우
                if (checkNotCleanedAreaExist(y, x)) {
                    // 방향 전환
                    rotate();

                    ny += dy[dir];
                    nx += dx[dir];
                    
                    // 청소되지 않은 빈칸이 아니라면 패스
                    if (isOutOfRange(ny, nx) || cleaned[ny][nx]) continue;
                } else {
                    // 반대 방향으로 진행하기 위한 임시 방향
                    int tempDir = (dir + 2) % 4;

                    ny += dy[tempDir];
                    nx += dx[tempDir];
                    
                    // 후진할 수 없다면 동작을 멈춤
                    if (isOutOfRange(ny, nx)) break;
                }
                y = ny;
                x = nx;
            }
        }

        // 4방향에 청소되지 않은 칸이 있는지 확인
        boolean checkNotCleanedAreaExist(int y, int x) {
            for (int d = 0; d < 4; d++) {
                int ny = y + dy[d];
                int nx = x + dx[d];
                if (!isOutOfRange(ny, nx) && !cleaned[ny][nx]) {
                    return true;
                }
            }
            return false;
        }
        
        // 반시계방향으로 90도 회전
        void rotate() {
            this.dir = (this.dir + 3) % 4;
        }
    }
}

 

 

GitHub - kwanik-kor/BOJ: Baekjoon Online Judge - explanation of solved problems and complete code

Baekjoon Online Judge - explanation of solved problems and complete code - GitHub - kwanik-kor/BOJ: Baekjoon Online Judge - explanation of solved problems and complete code

github.com

 

반응형

'Algorithm > 문제풀이' 카테고리의 다른 글

[ 백준 14499번 ] 주사위 굴리기  (0) 2023.03.03
[ 백준 2003번 ] 수들의 합2  (0) 2023.03.02
[ 백준 1759번 ] 암호 만들기  (1) 2023.03.01
[ 백준 2642번 ] 전개도  (0) 2023.02.21
[ 백준 20304 ] 비밀번호 제작  (0) 2023.02.18
profile

KwanIk Devlog

@갈닉

노력하는 개발자가 되고자 합니다. GitHub이나 블로그 모두 따끔한 피드백 부탁드립니다 :)