"0"과 "1"로 이루어진 지도인 board가 주어질 때, 로봇이 (N, N) 위치까지 이동하는데 필요한 최소 시간을 return 하도록 solution 함수를 완성해주세요.
제한사항
board의 한 변의 길이는 5 이상 100 이하입니다.
board의 원소는 0 또는 1입니다.
로봇이 처음에 놓여 있는 칸 (1, 1), (1, 2)는 항상 0으로 주어집니다.
로봇이 항상 목적지에 도착할 수 있는 경우만 입력으로 주어집니다.
BFS를 이용해 첫값을 넣고 방문자제거를 통해 해결하면 된다.
그런데 많이 봤던 칸이 하나가 아니라 2개를 움직이는것이라면 어떻게 해야하나?
회전이 들어가므로 상하좌우 그리고 회전반경 4개까지 한번에 8개를 체크해야한다.
칸 하나를 고정해서 문제를 풀면 편하게 가능하겠다.
BFS문제이고 구상은 쉽지만 칸이 2개라는점에 대해서 구현이 잘 생각안나는 문제였다.
결국 고정되는 값 하나만 생각하면 구현이 되는문제였다.
코드
import java.util.*;
class Solution {
public int solution(int[][] board) {
int answer = Integer.MAX_VALUE;
//상하좌우
int[] dx = {-1,1,0,0};
int[] dy = {0,0,-1,1};
//회전
int[][] rx = {{-1,0,-1,0},{0,0,1,1}};
int[][] ry = {{0,0,1,1},{-1,0,-1,0}};
boolean[][][] visit = new boolean[2][board.length][board[0].length];
Queue<robot> queue = new LinkedList<>();
queue.add(new robot(0,0,0,0));
visit[0][0][0] = true;
while(!queue.isEmpty()){
robot tmp = queue.poll();
//가로일때
if(tmp.dir==0&&tmp.x==board.length-1&&tmp.y==board.length-2){
answer = Math.min(answer,tmp.time);
continue;
}
//세로일때
if(tmp.dir==1&&tmp.x==board.length-2&&tmp.y==board.length-1){
answer = Math.min(answer,tmp.time);
continue;
}
//상하좌우
for(int i=0;i<4;i++){
int nx = tmp.x + dx[i];
int ny = tmp.y + dy[i];
//체크
if(!checkedBoard(nx,ny,board,tmp.dir)) continue;
if(!visit[tmp.dir][nx][ny]){
queue.add(new robot(nx,ny,tmp.dir,tmp.time+1));
visit[tmp.dir][nx][ny]=true;
}
}
//회전
for(int i=0;i<4;i++){
int nx = tmp.x + rx[tmp.dir][i];
int ny = tmp.y + ry[tmp.dir][i];
//회전가능한지 여부체크를 위한 x,y;
int cx=0;
int cy=0;
int ndir=0;
if(tmp.dir==0){
cx = tmp.x + dx[i%2];
cy = tmp.y + dy[i%2];
ndir = 1;
}else{
cx = tmp.x + dx[i<2?i+2:i];
cy = tmp.y + dy[i<2?i+2:i];
ndir = 0;
}
if(!checkedBoard(nx,ny,board,ndir)||!checkedBoard(cx,cy,board,tmp.dir)) continue;
if(!visit[ndir][nx][ny]){
queue.add(new robot(nx,ny,ndir,tmp.time+1));
visit[ndir][nx][ny]=true;
}
}
}
return answer;
}
boolean checkedBoard(int nx,int ny,int[][] board,int dir){
int n=board.length;
if(dir==0){
if(nx<0||ny<0||nx>=n||ny>=n||ny+1>=n||board[nx][ny]!=0||board[nx][ny+1]!=0) return false;
}else{
if(nx<0||ny<0||nx+1>=n||nx>=n||ny>=n||board[nx+1][ny]!=0||board[nx][ny]!=0) return false;
}
return true;
}
class robot{
int x;
int y;
int dir;
int time;
robot(int x,int y,int dir,int time){
this.x=x;
this.y=y;
this.dir=dir;
this.time=time;
}
}
}//큐를 통한 문제풀이