Algorithm/문제 풀이 / / 2023. 6. 16. 14:01

[BAEKJOON_14503 -JAVA] 로봇 청소기

반응형

문제

https://www.acmicpc.net/problem/14503

 

14503번: 로봇 청소기

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

www.acmicpc.net

 

JAVA코드

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

public class Main {

	private static int N, M;
	private static int[][] map;
	private static boolean[][] visited;
	private static int dy[] = { -1, 1, 0, 0 };
	private static int dx[] = { 0, 0, -1, 1 };

	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];
		visited = new boolean[N][M];

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

		for (int r = 0; r < N; r++) {
			st = new StringTokenizer(br.readLine());
			for (int c = 0; c < M; c++) {
				map[r][c] = Integer.parseInt(st.nextToken());
				visited[r][c] = map[r][c] == 1 ? true : false;
			}
		}

		System.out.println(start(robot));

	}

	public static int start(Robot robot) {
		int cnt = 0;

		while (true) {

			// 1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
			if (!visited[robot.getRow()][robot.getCol()]) {
				visited[robot.getRow()][robot.getCol()] = true;
				cnt++;
			}

			// 2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
			if (cleared(robot.getRow(), robot.getCol())) {
				// 1. 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
				robot.backward();
				if (isValid(robot.getRow(), robot.getCol()) && map[robot.getRow()][robot.getCol()] == 0) {
					continue;
				}

				// 2. 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
				return cnt;

			}
			// 3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
			else {
				// 1. 반시계 방향으로 90 회전한다.
				robot.turn();
				// 2. 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
				robot.forward();
				if (isValid(robot.getRow(), robot.getCol())
						&& !isWall(robot.getRow(), robot.getCol())
						&& !visited[robot.getRow()][robot.getCol()]) {
							// do nothing
				} else {
					robot.backward();
				}
				// 3. 1번으로 돌아간다.
				continue;
			}

		}
	}

	// index 유효성
	public static boolean isValid(int row, int col) {
		if (row < 0 || col < 0 || row >= N || col >= M)
			return false;

		return true;
	}

	// 벽 탐색
	public static boolean isWall(int row, int col) {
		if (map[row][col] == 1)
			return true;

		return false;
	}

	// 주변 4칸 청소 탐색
	public static boolean cleared(int row, int col) {
		for (int idx = 0; idx < 4; idx++) {
			int nextRow = row + dy[idx];
			int nextCol = col + dx[idx];

			if (!isValid(nextRow, nextCol))
				continue;

			if (!visited[nextRow][nextCol] && map[nextRow][nextCol] != 1) {
				return false;
			}
		}

		return true;
	}

	// d가 0인 경우 북쪽, 1인 경우 동쪽, 2인 경우 남쪽, 3인 경우 서쪽을 바라보고 있는 것이다.
	public static class Robot {
		private int row;
		private int col;
		private int dir;

		public Robot(int row, int col, int dir) {
			this.row = row;
			this.col = col;
			this.dir = dir;
		}

		// 반시계로 90도 회전
		public void turn() {
			if (this.dir == 0) {
				this.dir = 3;
			} else {
				this.dir -= 1;
			}
		}

		// 전진
		public void forward() {
			switch (this.dir) {
				case 0:
					this.row -= 1;
					break;
				case 1:
					this.col += 1;
					break;
				case 2:
					this.row += 1;
					break;
				case 3:
					this.col -= 1;
					break;
			}
		}

		// 후진
		public void backward() {
			switch (this.dir) {
				case 0:
					this.row += 1;
					break;
				case 1:
					this.col -= 1;
					break;
				case 2:
					this.row -= 1;
					break;
				case 3:
					this.col += 1;
					break;
			}
		}

		public int getRow() {
			return row;
		}

		public void setRow(int row) {
			this.row = row;
		}

		public int getCol() {
			return col;
		}

		public void setCol(int col) {
			this.col = col;
		}

		public int getDir() {
			return dir;
		}

		public void setDir(int dir) {
			this.dir = dir;
		}

	}
}
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유