0 0 0 0
0 0 a 0
0 0 1 1
0 0 1 0
a위치에 도달하는 방법은 두 가지 입니다.
첫째. 말의 움직임으로 한번에 (0,0)에서 a에 도달할 수 있습니다. -> 더 이상 말의 움직임으로 움직일 수 없기 때문에 (3,3)에 도달하지 못합니다.
둘째. 원숭이의 움직임으로 3번만에 (0,0)에서 a에 도달할 수 있습니다. -> 말의 움직임이 한번 남았기 때문에 1을 뛰어넘어 (3,3)에 도달할 수 있습니다.
이를 조금 더 확장시켜 생각해보면 board[i][j]에서 남은 말의 움직임이 몇 개냐에 따라 결과는 모두 달라집니다.
import java.io.*;
import java.util.*;
class Main {
static int[] M_dx = { 0, 1, 0, -1 };
static int[] M_dy = { 1, 0, -1, 0 };
static int[] H_dx = { -2, -2, -1, -1, 1, 1, 2, 2 };
static int[] H_dy = { -1, 1, -2, 2, -2, 2, -1, 1 };
static int r, c, k;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
k = sc.nextInt();
c = sc.nextInt();
r = sc.nextInt();
int[][] board = new int[r][c];
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
board[i][j] = sc.nextInt();
}
}
System.out.println(BFS(board));
}
public static int BFS(int[][] board) {
Queue<int[]> q = new LinkedList<int[]>();
int[] start = { 0, 0, k };
q.add(start);
boolean[][][] v = new boolean[r][c][k+1];
v[0][0][k] = true;
int cnt = 0;
while (!q.isEmpty()) {
int size = q.size();
cnt++;
while (--size >= 0) {
int[] now = q.poll();
if (now[0] == (r - 1) && now[1] == (c - 1)) return cnt - 1;
int jumpCnt = now[2];
// 원숭이
for (int d = 0; d < 4; d++) {
int nx = now[0] + M_dx[d];
int ny = now[1] + M_dy[d];
if (0 <= nx && nx < r && 0 <= ny && ny < c && board[nx][ny] == 0 && !v[nx][ny][jumpCnt]) {
v[nx][ny][jumpCnt] = true;
int[] temp2 = { nx, ny, jumpCnt };
q.add(temp2);
}
}
// 말
--jumpCnt;
if (jumpCnt < 0) continue;
for (int d = 0; d < 8; d++) {
int nx = now[0] + H_dx[d];
int ny = now[1] + H_dy[d];
if (0 <= nx && nx < r && 0 <= ny && ny < c && board[nx][ny] == 0 && !v[nx][ny][jumpCnt]) {
v[nx][ny][jumpCnt] = true;
int[] temp2 = { nx, ny, jumpCnt };
q.add(temp2);
}
}
}
}
return -1;
}
}