https://www.acmicpc.net/problem/1194
1194번: 달이 차오른다, 가자.
첫째 줄에 미로의 세로 크기 N과 가로 크기 M이 주어진다. (1 ≤ N, M ≤ 50) 둘째 줄부터 N개의 줄에 미로의 모양이 주어진다. 같은 타입의 열쇠가 여러 개 있을 수 있고, 문도 마찬가지이다. 그리고,
www.acmicpc.net
BFS + 비트마스킹으로 풀이하는 문제입니다.
벽부수기 같은 문제처럼 visited 체크를 열쇠의 소유상태에 따라 다르게 해줘야 합니다.
해당 부분을 비트마스킹 Integer로 저장하거나 배열을 통해 저장하거나 편한 방법으로 풀이할 수 있습니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class q1194_BOJ_달이차오른다가자 {
static StringTokenizer st;
static int[][] delta = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
static int R, C;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
char[][] map = new char[R][C];
boolean[][][] visited = new boolean[R][C][64];
Queue<Player> queue = new LinkedList<>();
for (int r = 0; r < R; r++) {
String input = br.readLine();
for (int c = 0; c < C; c++) {
map[r][c] = input.charAt(c);
if (map[r][c] == '0') {
queue.offer(new Player(r, c, 0));
visited[r][c][0] = true;
map[r][c] = '.';
}
}
}
int time = 0;
boolean flag = false;
loop: while (!queue.isEmpty()) {
int size = queue.size();
time++;
while (size-- > 0) {
Player p = queue.poll();
int x = p.x;
int y = p.y;
int key = p.key;
for (int i = 0; i < 4; i++) {
int nX = x + delta[i][0];
int nY = y + delta[i][1];
if (isIn(nX, nY) && map[nX][nY] != '#' && !visited[nX][nY][key]) {
if (map[nX][nY] == '.') {
queue.offer(new Player(nX, nY, key));
visited[nX][nY][key] = true;
} else if (map[nX][nY] == '1') {
flag = true;
break loop;
} else if (map[nX][nY] < 'a' && canOpen(map[nX][nY], key)) {
queue.offer(new Player(nX, nY, key));
visited[nX][nY][key] = true;
} else if (map[nX][nY] >= 'a') {
int nKey = (1 << (map[nX][nY] - 'a')) | key;
queue.offer(new Player(nX, nY, nKey));
visited[nX][nY][nKey] = true;
}
}
}
}
}
if (flag) {
System.out.println(time);
} else {
System.out.println("-1");
}
}
static boolean isIn(int x, int y) {
if (0 <= x && x < R && 0 <= y && y < C) {
return true;
}
return false;
}
static boolean canOpen(char door, int key) {
if ((1 << (door - 'A') & key) > 0) {
return true;
}
return false;
}
static class Player {
int x, y, key;
public Player(int x, int y, int key) {
this.x = x;
this.y = y;
this.key = key;
}
}
}
728x90
'🔍 알고리즘 > 백준 Java' 카테고리의 다른 글
[Java] 백준 2146번. 다리 만들기 (골드4) (0) | 2022.07.23 |
---|---|
[Java] 백준 1562번. 계단수 (골드1) (0) | 2022.07.22 |
[Java] 백준 12919번. A와B 2 (골드5) (0) | 2022.01.25 |
[Java] 백준 12904번. A와B (골드5) (0) | 2022.01.25 |
[Java] 백준 15810번. 풍선공장 (실버2) (0) | 2022.01.13 |