[ 문제 ]
- N×M크기의 배열로 표현되는 미로가 있다.
- 미로에서 1은 이동할 수 있는 칸을 나타내고, 0은 이동할 수 없는 칸을 나타낸다. 이러한 미로가 주어졌을 때, (1, 1)에서 출발하여 (N, M)의 위치로 이동할 때 지나야 하는 최소의 칸 수를 구하는 프로그램을 작성하시오. 한 칸에서 다른 칸으로 이동할 때, 서로 인접한 칸으로만 이동할 수 있다.칸을 셀 때에는 시작 위치와 도착 위치도 포함한다.
- 지나야 하는 최소의 칸 수를 출력한다. 항상 도착위치로 이동할 수 있는 경우만 입력으로 주어진다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static int[][] graph; // 그래프
static boolean[][] visited; // 방문한 위치 확인
static int[][] dr; // 방향을 담는 배열
static int num;
static int N;
static int M;
public static void main(String[] args) throws IOException {
// 방향 초기화
dr = new int[][]{{1,0},{-1,0}, {0, 1}, {0, -1}};
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); // 가로 길이
M = Integer.parseInt(st.nextToken()); // 세로 길이
graph = new int[N][M];
visited = new boolean[N][M];
// graph 정리
for(int i = 0 ; i < N ; i ++){
String[] str = br.readLine().split("");
for(int j = 0 ; j < M ; j ++){
graph[i][j] = Integer.parseInt(str[j]);
}
}
bfs(0, 0);
}
public static void bfs(int r, int c){
visited[r][c] = true;
Queue<int[]> tmp = new ArrayDeque<>();
tmp.add(new int[]{r, c, 1});
while(!tmp.isEmpty()){
int[] cur = tmp.poll();
int cr = cur[0];
int cc = cur[1];
int cnt = cur[2];
if(cr == N - 1 && cc == M - 1){
System.out.println(cnt);
break;
}
for(int i = 0 ; i < 4 ; i ++){
if(isVal(cr + dr[i][0], cc + dr[i][1]) && !visited[cr + dr[i][0]][cc + dr[i][1]] && graph[cr + dr[i][0]][cc + dr[i][1]] == 1){
visited[cr + dr[i][0]][cc + dr[i][1]] = true;
tmp.add(new int[]{cr + dr[i][0], cc + dr[i][1], cnt + 1});
}
}
}
}
public static boolean isVal(int r, int c){
// r,c 가 그래프 범위 내에 있는지?
return 0 <= r && r < N && 0 <= c && c < M;
}
}