728x90
1. 문제
https://www.acmicpc.net/problem/2178
N×M크기의 배열로 표현되는 미로가 있다. 미로에서 1은 이동할 수 있는 칸을 나타내고, 0은 이동할 수 없는 칸을 나타낸다. 이러한 미로가 주어졌을 때, (1, 1)에서 출발하여 (N, M)의 위치로 이동할 때 지나야 하는 최소의 칸 수를 구하는 프로그램을 작성하시오. 한 칸에서 다른 칸으로 이동할 때, 서로 인접한 칸으로만 이동할 수 있다.
위의 예에서는 15칸을 지나야 (N, M)의 위치로 이동할 수 있다. 칸을 셀 때에는 시작 위치와 도착 위치도 포함한다.
2. 풀이
BFS를 이용했다. 다음으로 가려고 하는 위치가 1) 범위에 벗어나지 않고 2-1) 저장된 값이 지금 새로 저장될 값보다 크거나 2-2) 아직 한 번도 방문하지 않은 위치일 때만 새로운 값을 저장한다.
새로운 값은 이전위치에 저장된 값+1이다.
원본에 덮어쓰는 방식이므로 마지막에 [n-1][m-1]값을 출력하면 된다.
import java.io.*;
import java.util.*;
public class BOJ_2178_미로탐색 {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[][] maze = new int[N][M];
for (int i = 0; i < N; i++) {
String line = in.readLine();
for (int j = 0; j < M; j++) {
maze[i][j] = line.charAt(j) - '0';
}
}
int[][] deltas = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{0, 0});
int[] v;
while (!queue.isEmpty()) {
v = queue.poll();
for (int d = 0; d < 4; d++) {
int ni = v[0] + deltas[d][0];
int nj = v[1] + deltas[d][1];
if (ni >= 0 && ni < N && nj >= 0 && nj < M && maze[ni][nj] != 0
&& (maze[ni][nj] > maze[v[0]][v[1]] + 1 || maze[ni][nj] == 1)) {
maze[ni][nj] = maze[v[0]][v[1]] + 1;
queue.offer(new int[]{ni, nj});
}
}
}
System.out.println(maze[N - 1][M - 1]);
}
}
3. 결과
'코딩테스트 > BOJ' 카테고리의 다른 글
[BOJ] 16236 아기상어 - JAVA (0) | 2022.02.23 |
---|---|
[BOJ] 2580 스도쿠 - JAVA (0) | 2022.02.23 |
[BOJ] 2567 색종이 2 - JAVA (0) | 2022.02.23 |
[BOJ] 1012 유기농 배추 - JAVA (0) | 2022.02.23 |
[BOJ] 2667 단지번호 붙이기 - JAVA (0) | 2022.02.23 |
댓글