hwooo
BOJ (Java) 1194번: 달이 차오른다, 가자. 본문
https://www.acmicpc.net/problem/1194



풀이
BFS로 탐색하되, visited 배열을 3차원을 만든다.
칸을 방문할 때 어떤 키를 가지고 방문했는지 확인해서, 같은 상태일 때 방문하는 걸 막는다.
key를 비트값으로 저장하여 문을 만났을 때 key가 있는지 확인한 후 있다면 방문이 가능하게 탐색한다.
Java 코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
public class Main {
static int N, M;
static char[][] map;
static boolean[][][] visited; // 어떤 key를 갖고 있을 때 방문했는지 확인
public static void main(String args[]) throws Exception {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String[] inputs = bf.readLine().split(" ");
N = Integer.parseInt(inputs[0]);
M = Integer.parseInt(inputs[1]);
// input
int[] start = new int[2];
map = new char[N][M];
visited = new boolean[N][M][1 << 7];
for (int i = 0; i < N; i++) {
String input = bf.readLine();
for (int j = 0; j < M; j++) {
map[i][j] = input.charAt(j);
if (map[i][j] == '0') {
start[0] = i;
start[1] = j;
}
}
}
findMinLen(start[0], start[1]);
}
private static void findMinLen(int r, int c) {
Queue<int[]> q = new ArrayDeque<>();
int[][] mv = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
q.add(new int[]{r, c, 0, 0});
visited[r][c][0] = true;
while (!q.isEmpty()) {
int[] now = q.poll();
r = now[0];
c = now[1];
int dis = now[2];
int keys = now[3];
// exit
if (map[r][c] == '1') {
System.out.println(dis);
return;
}
for (int i = 0; i < 4; i++) {
int nr = now[0] + mv[i][0];
int nc = now[1] + mv[i][1];
if (nr < 0 || nc < 0 || N <= nr || M <= nc || visited[nr][nc][keys]) continue;
// location : key
if (Character.isLowerCase(map[nr][nc])) {
int key = map[nr][nc] - 'a';
visited[nr][nc][keys | (1 << key)] = true; // 방문시 어떤 키를 갖고 있는 상태인지 체크
q.add(new int[]{nr, nc, dis + 1, keys | (1 << key)});
}
// location : door
else if (Character.isUpperCase(map[nr][nc])){
int door = map[nr][nc] - 'A';
// 키를 갖고 있다면 방문 가능
if ((keys & (1 << door)) != 0) {
visited[nr][nc][keys] = true;
q.add(new int[]{nr, nc, dis + 1, keys});
};
}
else if (map[nr][nc] != '#'){
visited[nr][nc][keys] = true;
q.add(new int[]{nr, nc, dis + 1, keys});
}
}
}
System.out.println(-1);
}
}'Study > Algorithm' 카테고리의 다른 글
| BOJ (Java) 3109번: 빵집 (0) | 2025.08.28 |
|---|---|
| BOJ (Java) 17472번: 다리 만들기 2 (0) | 2025.08.26 |
| BOJ (Java) 2146번: 다리 만들기 (0) | 2025.08.26 |
| BOJ (Java) 17490번: 일감호에 다리 놓기 (0) | 2025.08.20 |
| BOJ (Java) 14890번: 경사로 (0) | 2025.08.14 |