BOJ 14503: 로봇 청소기 https://www.acmicpc.net/problem/14503
왼쪽방향부터 차례대로 탐색을 진행
한다.왼쪽 방향
에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음
한 칸을 전진
하고 1번부터 진행한다.회전
하고 2번으로 돌아간다.바라보는 방향을 유지한 채
로 한 칸 후진
을 하고 2번으로 돌아간다.뒤쪽 방향이 벽이라 후진도 할 수 없는 경우
에는 작동을 멈춘다.방향 d
가 주어진다. d가 0인 경우에는 북쪽을, 1인 경우에는 동쪽을, 2인 경우에는 남쪽을, 3인 경우에는 서쪽을 바라보고 있는 것이다.DFS
를 사용하여 탐색한다.후진
한다는 조건이 있는데 이 부분이 DFS에서 그 이전 노드로 돌아가는 것
과 같다.import java.util.*;
import java.io.*;
public class Main {
static int N, M;
static int r, c, d;
static int[][] map;
static int[] dx = {-1, 0, 1, 0};
static int[] dy = {0, 1, 0, -1};
static int ans;
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()); // 가로 크기
st = new StringTokenizer(br.readLine(), " ");
r = Integer.parseInt(st.nextToken()); // 좌표 초깃값
c = Integer.parseInt(st.nextToken());
d = Integer.parseInt(st.nextToken()); // 초기 방향
map = new int[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());
}
}
ans = 0;
clean(r, c, d);
System.out.println(ans);
}
static void clean(int x, int y, int dir) {
// 현재 위치 청소
if(map[x][y] == 0) {
map[x][y] = 2; // 청소한 자리는 2를 넣음
ans++; // 청소한 위치 카운트
}
// 왼쪽 방향부터 탐색
boolean beAbleToClean = false; // 청소할 수 있는 위치인지 체크하는 변수
int nowDir = dir;
for(int i=0; i<4; i++) {
int nDir = (dir + 3) % 4; // 시계 방향으로 북동남서(0123)이기 때문에 +3을 해주고 4로 나눔
//-> 반시계 방향으로 돌면서 탐색하는 것과 같음
int nx = x + dx[nDir];
int ny = y + dy[nDir];
// 청소할 수 있는 위치 이면
if(map[nx][ny] == 0) {
clean(nx, ny, nDir); // 왼쪽 위치를 파라미터로 넘김
beAbleToClean = true;
break;
}
dir = nDir;
}
// 네 방향 모두 이미 청소됐거나 벽일 때
if(!beAbleToClean) {
int nDir = (dir + 2) % 4; // 후진함
int nx = x + dx[nDir];
int ny = y + dy[nDir];
// 후진 한 위치가 벽이 아니면 탐색 시작
if(map[nx][ny] != 1) {
clean(nx, ny, nowDir); // 방향 유지한 채 후진 한 위치를 파라미터로 넘김
}
}
}
}