[BOJ 14503, Java] 로봇 청소기

TraceofLight·2023년 2월 18일
0

ProblemSolving

목록 보기
8/21
post-thumbnail

문제 링크

BOJ 14503

분류

구현(implementation), 시뮬레이션(simulation)

설명

전형적인 구현 문제인데 문제 설명을 이해하는 것부터 좀 난해한 부분이 있다. 해당 부분에 대해서만 간단하게 첨언을 해볼까 한다.

  1. 현재 칸을 청소
  2. 현재 칸을 기준으로 반시계로 90도 회전한 방향부터 체크
  3. 한 바퀴 다 돌아서 처음에 보고 있던 위치까지 확인한 후 청소할 곳이 없다면 후진
  4. 후진할 곳도 없다면 청소 종료

해당 문제에서 정면 기준 왼쪽 먼저 체크한다는 부분을 간과하고 풀게 된다면 구현이고 뭐고 계속 헤맬 수 밖에 없는 구조를 가지고 있다. 그 점을 반드시 주의해서 풀도록 하자!

풀이 코드

import java.io.*;
import java.util.*;

public class Main {

    public static int height;
    public static int width;

    public static boolean isNeedClean(int[][] table, int nowYIndex, int nowXIndex) {
        return table[nowYIndex][nowXIndex] == 0;
    }

    public static void main(String[] args) throws IOException {

        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out));

        StringTokenizer mapSize = new StringTokenizer(input.readLine(), "[ ]");

        // 뒷 방향 등록 해시맵 선언
        HashMap<Integer, Integer> backward = new HashMap<>();
        backward.put(0, 2);
        backward.put(2, 0);
        backward.put(1, 3);
        backward.put(3, 1);


        height = Integer.parseInt(mapSize.nextToken());
        width = Integer.parseInt(mapSize.nextToken());

        int[][] mapInfo = new int[height][width];

        StringTokenizer startingPoint = new StringTokenizer(input.readLine(), "[ ]");

        int nowY = Integer.parseInt(startingPoint.nextToken());
        int nowX = Integer.parseInt(startingPoint.nextToken());
        int nowDirection = Integer.parseInt(startingPoint.nextToken());

        for (int i = 0; i < height; i++) {
            StringTokenizer mapLine = new StringTokenizer(input.readLine(), "[ ]");

            for (int j = 0; j < width; j++) {
                mapInfo[i][j] = Integer.parseInt(mapLine.nextToken());
            }

        }

        int cleanCounter = 0;

        int[] directionY = new int[]{-1, 0, 1, 0};
        int[] directionX = new int[]{0, 1, 0, -1};

        Loop:
        while (true) {

            // 현재 칸이 청소가 필요하다면 청소 실시
            if (isNeedClean(mapInfo, nowY, nowX)) {
                mapInfo[nowY][nowX] = 2;
                cleanCounter += 1;
            }

            // 주변 칸에 대해서 확인
            for (int i = 1; i < 5; i++) {

                int targetDirection = (nowDirection + 4 - i) % 4;
                int targetY = nowY + directionY[targetDirection];
                int targetX = nowX + directionX[targetDirection];

                // 청소할 칸이 있는 경우 이동 및 방향 전환
                if (isNeedClean(mapInfo, targetY, targetX)) {
                    nowY = targetY;
                    nowX = targetX;
                    nowDirection = targetDirection;
                    break;
                }

                // 청소할 칸이 없는 경우 뒷칸 확인
                if (i == 4) {
                    targetY = nowY + directionY[backward.get(nowDirection)];
                    targetX = nowX + directionX[backward.get(nowDirection)];

                    // 뒤로 이동할 수 없는 경우 청소 종료
                    if (mapInfo[targetY][targetX] == 1) {
                        break Loop;

                        // 이동할 수 있다면 뒤로 1칸 후진
                    } else {
                        nowY = targetY;
                        nowX = targetX;
                    }
                }

            }

        }

        // 이동 결과 출력
        output.write(Integer.toString(cleanCounter));

        output.flush();
        output.close();

    }

}
profile
24시간은 부족한 게 맞다

0개의 댓글