문제 링크는 여기.
초기 방의 상태와 로봇 청소기의 위치, 방향이 주어진다. 방은 N*M의 배열 형태이며, 0은 청소가 되지 않은 곳, 1은 벽을 의미한다. 로봇 청소기의 첫 위치는 항상 벽이 아니다.
로봇청소기는 아래의 로직에 따라 청소를 수행한다.
로봇 청소기가 최종적으로 청소한 칸의 개수를 출력하면 된다.
단순 구현문제로, 위의 로봇청소기 로직만 잘 구현하면 된다.
유의할 점은, 입력으로 주어지는 초기 로봇의 방향은 0:북, 1:동, 2:남, 3:서 이지만, 막상 로직에서는 왼쪽을 확인하므로 (d+3)%d을 해주어야 된다는 것이다.
move 함수는 다음과 같다.
나의 경우 로봇청소기 로직 중 1번을 2-a 이후에 수행하게끔 변형하여 구현했다.
//public static int[] dr = { -1, 0, 1, 0 };
//public static int[] dc = { 0, 1, 0, -1 };
public static boolean move() {
int i = 0;
for (; i < 4; i++) {
D = (D + 3) % 4;
if (arr[R + dr[D]][C + dc[D]] == 0)
break;
}
if (i == 4) {
R -= dr[D];
C -= dc[D];
return arr[R][C]!=1;
}
R += dr[D];
C += dc[D];
// 이미 청소했음을 표시
arr[R][C] = 2;
result++;
return true;
}
main 함수는 다음과 같다.
// 초기 로봇의 위치는 무조건 청소할 수 있으므로 result = 1로 시작
public static int N, M, R, C, D, result = 1;
public static int[][] arr;
public static int[] dr = { -1, 0, 1, 0 };
public static int[] dc = { 0, 1, 0, -1 };
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr = new int[N][M];
// 초기 로봇 청소기 정보 저장
st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
D = Integer.parseInt(st.nextToken());
// 방의 정보 저장
for (int n = 0; n < N; n++) {
st = new StringTokenizer(br.readLine());
for (int m = 0; m < M; m++) {
arr[n][m] = Integer.parseInt(st.nextToken());
}
}
// ****** 초기 위치 청소했다고 치고 표시 ******
arr[R][C] = 2;
// 더 이상 못 움직일 때까지 청소
while (move());
System.out.println(result);
}
최종 제출한 코드는 다음과 같다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int N, M, R, C, D, result = 1;
public static int[][] arr;
public static int[] dr = { -1, 0, 1, 0 };
public static int[] dc = { 0, 1, 0, -1 };
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr = new int[N][M];
st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
D = Integer.parseInt(st.nextToken());
for (int n = 0; n < N; n++) {
st = new StringTokenizer(br.readLine());
for (int m = 0; m < M; m++) {
arr[n][m] = Integer.parseInt(st.nextToken());
}
}
arr[R][C] = 2;
while (move());
System.out.println(result);
}
public static boolean move() {
int i = 0;
for (; i < 4; i++) {
D = (D + 3) % 4;
if (arr[R + dr[D]][C + dc[D]] == 0)
break;
}
if (i == 4) {
R -= dr[D];
C -= dc[D];
return arr[R][C]!=1;
}
R += dr[D];
C += dc[D];
arr[R][C] = 2;
result++;
return true;
}
}
제출 결과는 다음과 같다.

첫 번째는 위에서 주석으로 ***표시한 초기위치 청소 표시를 안해줘서 틀렸다… 두 번째와 세 번째 차이는 따로 없다. 두 번째 제출 때 디버깅용 print() 함수를 만들어 쓴 후 지우지 않고 제출했길래 다시 지우고 제출한 것이다.
첫 번째는 교육원에서 풀고 따로 코드를 옮겨오지 않아서 그냥 집에서 새로 짰는데, 다시 두 코드를 비교하니 그냥 완전 똑같은 코드였다. 물론 하루 전에 짠 것이니 그랬던 것일 수 있지만… 내 머리 자체가 함수 마냥 같은 문제엔 항상 같은 풀이를 떠올리는 것 같다는 생각이 들었다.