반응형
문제
https://www.acmicpc.net/problem/14503
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;
}
}
}
반응형
'Algorithm > 문제 풀이' 카테고리의 다른 글
[BAEKJOON_19637 - JAVA] IF문 좀 대신 써줘 (0) | 2023.06.17 |
---|---|
[BAEKJOON_1446 - JAVA] 지름길 (0) | 2023.06.16 |
[BAEKJOON_15723 - JAVA] n단 논법 (0) | 2023.06.16 |
[BAEKJOON_11726 - JAVA] 2×n 타일링 (0) | 2022.12.07 |
[BAEKJOON_17615 - JAVA] 볼 모으기 (0) | 2022.12.07 |