보물섬 지도에서 보물이 묻혀 있는 두 지점을 찾아,
서로 간의 최단 거리로 이동하는 데 걸리는 시간(칸 수) 중 가장 긴 시간을 구하는 문제이다.
L(육지)과 W(바다)로 구성된다.L끼리만 인접 이동 가능하며, 같은 곳을 두 번 이상 지나갈 수 없다.👉 출력 : 가장 멀리 떨어진 두 육지(L) 사이의 최단 거리(이동 칸 수)
모든 육지(L)에서 BFS 탐색 수행
BFS로 최단거리 탐색
dist 배열을 사용하여 현재 위치까지 이동한 칸 수를 저장중복 방문 방지
visited 배열을 새로 초기화하여| 변수 | 설명 |
|---|---|
x, y | 지도 크기 (행, 열) |
arr[][] | 지도 정보 (L, W) |
visited[][] | 방문 체크용 |
dx, dy | 상하좌우 이동 방향 |
ans | 최종 결과값 (가장 긴 최단거리) |
x), 열(y), 지도 데이터(arr[][]) 받기L(육지)일 경우 BFS 탐색 수행ans에 저장ans 출력50 x 50 = 2500O(N*M*N*M) → 약 6,250,000 연산모든 간선의 가중치가 동일한 그래프(또는 격자)에서 한 지점에서 다른 지점까지의 '최단 거리'를 구하기에 적합하다.
DFS(깊이 우선 탐색)는 경로의 깊이에 따라 불필요하게 멀리 탐색할 수 있지만 BFS는 가까운 칸부터 순차적으로 탐색하므로 '최소 이동 거리'를 보장할 수 있다.
문제에서 요구하는 것은 "한 육지에서 다른 육지까지의 최단 거리 중 최댓값"이므로,
각 육지를 시작점으로 BFS를 수행해 해당 지점에서 도달 가능한 최장 거리(farthest)를 구하는 것이 최적의 접근법이다.

package Baekjoon;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;
public class B_2589_보물섬 {
static int x, y;
static char[][] arr;
static boolean[][] visited;
static int[] dx = {-1,1,0,0};
static int[] dy = {0,0,-1,1};
public static void main(String[] args) {
// 육지(L) / 바다(W)
// 보물은 서로 간에 최단 거리로 이동하는 데 있어 가장 긴 시간이 걸리는 육지 두 곳에 나뉘어 묻혀있다.
// 같은 곳을 두 번 이상 지나가거나, 멀리 돌아가서는 안 된다.
Scanner sc = new Scanner(System.in);
x = sc.nextInt();
y = sc.nextInt();
arr = new char[x][y];
visited = new boolean[x][y];
for (int i = 0; i < x; i++) {
String line = sc.next();
for (int j = 0; j < y; j++) {
arr[i][j] = line.charAt(j);
}
}
int ans = 0;
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
if (arr[i][j] == 'L') ans = Math.max(ans, bfs(i, j));
}
}
System.out.println(ans);
}
// BFS로 시작점(sr, sc)에서 가장 먼 육지까지의 거리 계산
static int bfs(int sr, int sc) {
Deque<int[]> q = new ArrayDeque<>();
boolean[][] visited = new boolean[x][y];
int[][] dist = new int[x][y];
visited[sr][sc] = true;
q.add(new int[]{sr, sc});
int farthest = 0; // 시작점에서 가장 먼 거리
while (!q.isEmpty()) {
int[] cur = q.poll();
int r = cur[0], c = cur[1];
for (int d = 0; d < 4; d++) {
int nr = r + dx[d];
int nc = c + dy[d];
// 1) 경계 검사
if (nr < 0 || nr >= x || nc < 0 || nc >= y) continue;
// 2) 이동 가능한 칸인지 검사
if (arr[nr][nc] != 'L') continue;
// 3) 방문 여부 확인
if (visited[nr][nc]) continue;
visited[nr][nc] = true;
dist[nr][nc] = dist[r][c] + 1;
farthest = Math.max(farthest, dist[nr][nc]);
q.add(new int[]{nr, nc});
}
}
return farthest; // 가장 먼 육지까지의 최단거리 반환
}
}
static int bfs(int sr, int sc) {
Deque<int[]> q = new ArrayDeque<>();
boolean[][] visited = new boolean[x][y];
int[][] dist = new int[x][y];
}
visited[sr][sc] = true;
q.add(new int[]{sr, sc});
while (!q.isEmpty()) {
int[] cur = q.poll();
int r = cur[0], c = cur[1];
}
if (nr < 0 || nr >= x || nc < 0 || nc >= y) continue; // 지도 범위
if (arr[nr][nc] != 'L') continue; // 육지인지 검사
if (visited[nr][nc]) continue; // 이미 방문했는지 검사
visited[nr][nc] = true;
dist[nr][nc] = dist[r][c] + 1;
farthest = Math.max(farthest, dist[nr][nc]);
q.add(new int[]{nr, nc});
return farthest;