728x90
문제
풀이
처음 문제를 이해하는 데 어려워서 백준의 질문게시판을 보고 문제를 이해하게 되었다.
1) 청소기의 위치에서 사방으로 청소할 칸이 있는 경우
1. 반시계 방향으로 회전
2-1. 청소기가 바라보고 있는 방향이 청소할 칸인 경우
I. 바라보고 있는 방향으로 이동
II. 1)로 이동
2-2 청소기가 바라보고 있는 방향이 청소할 칸이 아닌 경우
I. 1)로 이동
2) 청소기의 위치에서 사방으로 청소할 칸이 없는 경우
1. 청소기가 바라보고 있는 방향의 반대 방향이 벽이 아닌 경우
I. 청소기가 바라보고 있는 방향의 반대로 이동
II. 1)로 이동
2. 청소기가 바라보고 있는 방향의 반대방향이 벽인 경우
I. 정지
위의 규칙에 의해 청소를 수행할 method와 후진을 할 method로 분리해서 코드를 작성했다.
정답코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static int N;
static int M;
static int sx;
static int sy;
static int direction;
static int[][] map;
static boolean[][] visited;
static int[] dx = {1, 0 , -1, 0}; // 상하좌우 계산할 x좌표
static int[] dy = {0, 1, 0, -1}; // 상하좌우 계산할 y좌표
static int cleanCount = 0;
static int nowX;
static int nowY;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
sx = Integer.parseInt(st.nextToken());
sy = Integer.parseInt(st.nextToken());
direction = Integer.parseInt(st.nextToken());
map = new int[N][M];
visited = 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());
}
}
cleanCount++;
nowX = sx;
nowY = sy;
visited[nowX][nowY] = true;
clean();
System.out.println(cleanCount);
}
static void clean() {
boolean notClean = false;
for(int i = 0; i < 4; i++) {
int nextX = dx[i] + nowX;
int nextY = dy[i] + nowY;
if(nextX >= 0 && nextX < N && nextY >= 0 && nextY < M && map[nextX][nextY] == 0 && !visited[nextX][nextY]) {
notClean = true;
}
}
// 청소되지 않은 칸이 있다면
if(notClean) {
// 회전
direction = direction - 1 < 0 ? 3 : direction - 1;
drive();
} else {
back();
}
}
// 청소
static void drive() {
int moveX = 0;
int moveY = 0;
if(direction == 0) {
moveX = nowX - 1;
moveY = nowY;
} else if(direction == 1) {
moveX = nowX;
moveY = nowY + 1;
} else if(direction == 2) {
moveX = nowX + 1;
moveY = nowY;
} else if(direction == 3) {
moveX = nowX;
moveY = nowY - 1;
}
// 칸이 방 안이고 청소되지 않은 곳이라면
if(moveX >= 0 && moveX < N && moveY >= 0 && moveY < M && map[moveX][moveY] == 0 && !visited[moveX][moveY]) {
visited[moveX][moveY] = true;
cleanCount++;
nowX = moveX;
nowY = moveY;
}
clean();
}
// 후진
static void back() {
int moveX = 0;
int moveY = 0;
if(direction == 0) {
moveX = nowX + 1;
moveY = nowY;
} else if(direction == 1) {
moveX = nowX;
moveY = nowY - 1;
} else if(direction == 2) {
moveX = nowX - 1;
moveY = nowY;
} else if(direction == 3) {
moveX = nowX;
moveY = nowY + 1;
}
// 칸이 방안이고 벽이 아닌 경우
if(moveX >= 0 && moveX < N && moveY >= 0 && moveY < M && map[moveX][moveY] == 0) {
nowX = moveX;
nowY = moveY;
clean();
}
}
}
문의사항이나 피드백은 댓글로 남겨주세요.
'백준' 카테고리의 다른 글
[백준] 18185번: 라면 사기 - JAVA (1) | 2025.02.06 |
---|---|
[백준] 9205번: 맥주 마시면서 걸어가기 - JAVA (2) | 2025.02.06 |
[백준] 2573번: 빙산 - JAVA (0) | 2025.02.05 |
[백준] 2468번: 안전 영역 - JAVA (0) | 2025.02.05 |
[백준] 5014번: 스타트링크 - JAVA (0) | 2025.02.05 |