봇개발자 "무지"는 한 달 앞으로 다가온 "카카오배 로봇경진대회"에 출품할 로봇을 준비하고 있습니다. 준비 중인 로봇은 2 x 1 크기의 로봇으로 "무지"는 "0"과 "1"로 이루어진 N x N 크기의 지도에서 2 x 1 크기인 로봇을 움직여 (N, N) 위치까지 이동 할 수 있도록 프로그래밍을 하려고 합니다. 로봇이 이동하는 지도는 가장 왼쪽, 상단의 좌표를 (1, 1)로 하며 지도 내에 표시된 숫자 "0"은 빈칸을 "1"은 벽을 나타냅니다. 로봇은 벽이 있는 칸 또는 지도 밖으로는 이동할 수 없습니다. 로봇은 처음에 아래 그림과 같이 좌표 (1, 1) 위치에서 가로방향으로 놓여있는 상태로 시작하며, 앞뒤 구분없이 움직일 수 있습니다.
"0"과 "1"로 이루어진 지도인 board가 주어질 때, 로봇이 (N, N) 위치까지 이동하는데 필요한 최소 시간을 return 하도록 solution 함수를 완성해주세요.
board의 한 변의 길이는 5 이상 100 이하입니다.
board의 원소는 0 또는 1입니다.
로봇이 처음에 놓여 있는 칸 (1, 1), (1, 2)는 항상 0으로 주어집니다.
로봇이 항상 목적지에 도착할 수 있는 경우만 입력으로 주어집니다.
import java.util.*;
class Solution {
public int solution(int[][] board) {
int m=board.length, n=board[0].length, cnt=0;
// visit은 최소 값의 좌표로 체크한다.
// 0:hor/1:ver
boolean[][][] visit = new boolean[2][m][n];
Queue<int[]> q = new LinkedList<>();
// i1, j1, i2, j2, 0:hor/1:ver
q.offer(new int[]{0,0,0,1,0});
while(!q.isEmpty()) {
int size = q.size();
for(int i=0 ; i<size ; i++) {
int[] p = q.poll();
// Range 확인
if(checkMap(p[0], p[1], p[2], p[3], m, n, visit[p[4]], board)) continue;
// 끝
if(p[2]==m-1 && p[3]==n-1) return cnt;
// visit
visit[p[4]][p[0]][p[1]] = true;
q.offer(new int[]{p[0], p[1]-1, p[2], p[3]-1, p[4]});
q.offer(new int[]{p[0], p[1]+1, p[2], p[3]+1, p[4]});
q.offer(new int[]{p[0]-1, p[1], p[2]-1, p[3], p[4]});
q.offer(new int[]{p[0]+1, p[1], p[2]+1, p[3], p[4]});
if(p[4]==0) {
// hor
int r = p[0];
if(r+1<m && board[r+1][p[1]]==0 && board[r+1][p[3]]==0) {
q.offer(new int[]{r, p[1], r+1, p[1], 1});
q.offer(new int[]{r, p[3], r+1, p[3], 1});
}
if(r-1>=0 && board[r-1][p[1]]==0 && board[r-1][p[3]]==0) {
q.offer(new int[]{r-1, p[1], r, p[1], 1});
q.offer(new int[]{r-1, p[3], r, p[3], 1});
}
} else {
// ver
int c = p[1];
if(c+1<n && board[p[0]][c+1]==0 && board[p[2]][c+1]==0) {
q.offer(new int[]{p[0], c, p[0], c+1, 0});
q.offer(new int[]{p[2], c, p[2], c+1, 0});
}
if(c-1>=0 && board[p[0]][c-1]==0 && board[p[2]][c-1]==0) {
q.offer(new int[]{p[0], c-1, p[0], c, 0});
q.offer(new int[]{p[2], c-1, p[2], c, 0});
}
}
}
cnt++;
}
return -1;
}
public boolean checkMap(int i1, int j1, int i2, int j2, int m, int n, boolean[][] visit, int[][] board) {
if(i1<0 || i2>=m || j1<0 || j2>=n || visit[i1][j1]) return true;
else if(board[i1][j1]==1 || board[i2][j2]==1) return true;
return false;
}
}