로봇 청소기의 이동 = 바라보는 방향이 존재
처음 빈칸은 전부 청소되지 않은 상태
- 현재 칸이 청소되지 않은 경우 현재 칸을 청소
- 현재 칸의 주변 4칸 중 청소되지 않은 빈칸이 없는 경우
- 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로
- 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
- 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우
- 반시계 방향으로 90도 회전한다.
- 바라보는 방향을 기준으로 앞쪽이 청소되지 않은 빈칸인 경우 한 칸 전진한다.
- 1번으로 돌아간다.
필요한 기능을 정리해보자.
- 현재 위치의 청소 여부 판단
- 주변 4칸의 청소 여부 판단
- 후진
- 전진
- 반시계 90도 회전
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static FastReader scan = new FastReader();
static int[][] DIRECTION = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}}; // 북서남동
static int N, M;
static Robot robot;
static int[][] map;
static class Robot {
int r;
int c;
int d;
public Robot(int r, int c, int d) {
this.r = r;
this.c = c;
this.d = d;
}
void moveForward() {
r += DIRECTION[d][0];
c += DIRECTION[d][1];
}
void moveBack() {
r -= DIRECTION[d][0];
c -= DIRECTION[d][1];
}
void rotate() {
d = (d + 1) % 4;
}
}
static class Room {
int[][] map;
Robot robot;
int cleanCount;
public Room(int[][] map, Robot robot) {
this.map = map;
this.robot = robot;
}
public void clean() {
while (true) {
if (map[robot.r][robot.c] == 0) {
map[robot.r][robot.c] = 2;
cleanCount++;
}
// 주변 4칸을 탐색
if (existUncleanRoom(map, robot.r, robot.c)) {
// 4칸 중 청소되지 않은 빈 칸이 존재한다.
for (int i = 0; i < 4; i++) {
robot.rotate();
int nr = robot.r + DIRECTION[robot.d][0];
int nc = robot.c + DIRECTION[robot.d][1];
if (nr < 0 || nr >= N || nc < 0 || nc >= M) {
continue;
}
if (map[nr][nc] == 0) {
robot.moveForward();
break;
}
}
} else {
// 4방향 다 봤는데 청소되지 않은 칸이 없다.
robot.moveBack();
if (map[robot.r][robot.c] == 1) {
// 후진했는데 벽인 경우 종료
return;
}
}
}
}
private boolean existUncleanRoom(int[][] map, int r, int c) {
for (int d = 0; d < 4; d++) {
if (map[r + DIRECTION[d][0]][c + DIRECTION[d][1]] == 0) {
return true;
}
}
return false;
}
public int getCleanCount() {
return cleanCount;
}
}
static void input() {
N = scan.nextInt();
M = scan.nextInt();
map = new int[N][M];
// 로복 좌표, 방향
int r = scan.nextInt();
int c = scan.nextInt();
int d = scan.nextInt();
if (d == 0) {
// 북
d = 0;
} else if (d == 1) {
// 동
d = 3;
} else if (d == 2) {
// 남
d = 2;
} else {
//서
d = 1;
}
robot = new Robot(r, c, d);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
map[i][j] = scan.nextInt(); // 0 빈칸 1 벽
}
}
}
public static void main(String[] args) {
input();
Room room = new Room(map, robot);
room.clean();
System.out.println(room.getCleanCount());
}
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
}
'Algorithm > BOJ' 카테고리의 다른 글
BOJ 14889 - 스타트와 링크 (1) | 2024.10.11 |
---|---|
BOJ 14888 - 연산자 끼워넣기 (1) | 2024.10.10 |
BOJ 14502 - 연구소 (0) | 2024.10.10 |
BOJ 14501 - 퇴사 (1) | 2024.10.09 |
BOJ 14500 - 테트로미노 (1) | 2024.10.09 |