7x7 격자판 미로를 탈출하는 최단경로의 길이를 구하는 문제를 해결하기 위해 BFS(너비 우선 탐색) 알고리즘을 사용한다. BFS는 출발점에서 도착점까지 도달할 수 있는 모든 경로를 '너비'로 확장해 나가며 최단 경로를 구하는 알고리즘이다.
문제 설명
격자판의 좌표 (1, 1)에서 출발하여 (7, 7)에 도착하는 최단 경로의 길이를 출력한다. 격자판의 각 칸은 벽(1) 또는 도로(0)로 이루어져 있으며, 이동할 수 있는 방향은 상, 하, 좌, 우로 한 칸씩 이동한다. 도착점에 도달할 수 없는 경우 -1을 출력한다.
위 미로에서 최단 경로는 총 12칸을 이동한 것이다.
예시 입력
0 0 0 0 0 0 0
0 1 1 1 1 1 0
0 0 0 1 0 0 0
1 1 0 1 0 1 1
1 1 0 1 0 0 0
1 0 0 0 1 0 0
1 0 1 0 0 0 0
예시 출력
12
BFS 알고리즘의 특징
BFS는 시작점에서 출발하여 같은 거리의 모든 좌표를 먼저 탐색한 후, 그다음으로 거리가 증가하는 좌표들을 차례대로 탐색한다. 즉, 너비를 우선으로 탐색하기 때문에 모든 가능한 경로를 균형 있게 고려할 수 있다.
BFS 탐색의 동작 원리
- 출발점 (1, 1)에서 시작하여 상하좌우 네 방향을 모두 탐색한다.
- 가능한 경로는 모두 큐에 넣고, 같은 거리에 있는 점을 모두 방문한 후 다음 단계로 넘어간다.
- 이렇게 같은 거리의 좌표를 먼저 탐색하므로 최단 거리를 구할 수 있다.
- 한 번 방문한 좌표는 다시 방문하지 않도록 체크한다.
BFS 탐색 흐름
- Step 1: 시작점 (1, 1)에서 상하좌우로 탐색하여 갈 수 있는 좌표 (1, 2)와 (2, 1)을 큐에 넣는다.
- Step 2: (1, 2)와 (2, 1)에서 다시 상하좌우로 탐색하여 다음으로 갈 수 있는 좌표들을 큐에 넣는다.
- Step 3: 큐에서 꺼낸 좌표들을 탐색하여 도착점 (7, 7)까지 도달할 때까지 반복한다.
큐를 이용한 BFS 시각화
- (1,1)에서 출발하여 상하좌우로 갈 수 있는 모든 경로를 큐에 넣는다.
- 같은 거리의 모든 경로를 먼저 탐색하고, 그다음 거리로 확장해 나간다.
- 도착점에 도달했을 때 최단 경로의 길이를 계산한다.
코드 구현
package com.example.codingtest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
class Point {
public int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Main {
static int[] dx = {-1, 0, 1, 0};
static int[] dy = {0, 1, 0, -1};
static int[][] board, dis;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
board = new int[8][8]; // 1부터 7까지 사용하므로 8x8 배열 선언
dis = new int[8][8]; // 거리 저장을 위한 배열
// 입력받은 미로 데이터를 board 배열에 저장
for (int i = 1; i <= 7; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 1; j <= 7; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
// BFS 탐색 시작
BFS(1, 1);
// 도착점까지의 거리를 출력
if (dis[7][7] == 0) {
System.out.println(-1); // 도착할 수 없으면 -1 출력
} else {
System.out.println(dis[7][7]); // 도착점까지의 최단 거리 출력
}
}
public static void BFS(int x, int y) {
Queue<Point> queue = new LinkedList<>();
queue.offer(new Point(x, y)); // 시작점 큐에 넣기
board[x][y] = 1; // 방문 표시
while (!queue.isEmpty()) {
Point tmp = queue.poll(); // 큐에서 좌표 꺼내기
for (int i = 0; i < 4; i++) {
int nx = tmp.x + dx[i];
int ny = tmp.y + dy[i];
// 유효한 범위 내에서 이동할 수 있는 좌표인지 확인
if (nx >= 1 && nx <= 7 && ny >= 1 && ny <= 7 && board[nx][ny] == 0) {
board[nx][ny] = 1; // 방문 표시
queue.offer(new Point(nx, ny)); // 큐에 새로운 좌표 추가
dis[nx][ny] = dis[tmp.x][tmp.y] + 1; // 이동 거리 기록
}
}
}
}
}
코드 설명
- Point 클래스: 좌표를 저장하는 클래스이다. x, y 좌표를 관리한다.
- board 배열: 미로의 상태를 저장한다. 1은 벽, 0은 도로를 나타낸다.
- dis 배열: 각 좌표까지의 이동 거리를 저장하는 배열이다. 출발점에서 도착점까지의 최단 거리를 계산할 수 있다.
- BFS 메서드: 큐를 이용해 미로를 탐색한다. 상하좌우로 이동할 수 있는 모든 좌표를 탐색하며, 방문한 좌표는 다시 방문하지 않도록 처리한다.
BFS의 장점
BFS는 너비 우선 탐색 방식이므로 가장 먼저 도착점에 도달하는 경로가 최단 경로가 된다. 탐색을 할 때 한 번에 한 단계씩 이동하므로 경로의 길이를 정확하게 측정할 수 있다.
결론
BFS 알고리즘을 활용하면 7x7 미로에서 출발점에서 도착점까지의 최단 경로를 효율적으로 찾을 수 있다. BFS는 큐를 사용하여 탐색하는 너비 우선 탐색 방식으로, 같은 거리의 모든 경로를 동시에 탐색하여 최단 경로를 구한다.
'Algorithm > 기타' 카테고리의 다른 글
섬나라 아일랜드(BFS) (0) | 2024.10.19 |
---|---|
섬나라 아일랜드(DFS) (1) | 2024.10.19 |
미로탐색(DFS) (0) | 2024.10.19 |
수열 추측하기(DFS) (0) | 2024.10.19 |
조합의 경우수(메모이제이션) (0) | 2024.10.18 |