[프로그래머스] 블록 이동하기 (JAVA)

유존돌돌이·2022년 1월 25일
0

Programmers

목록 보기
154/167
post-thumbnail

문제 설명

봇개발자 "무지"는 한 달 앞으로 다가온 "카카오배 로봇경진대회"에 출품할 로봇을 준비하고 있습니다. 준비 중인 로봇은 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으로 주어집니다.
로봇이 항상 목적지에 도착할 수 있는 경우만 입력으로 주어집니다.

Code

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;
	}
}

0개의 댓글