알고리즘/문제풀이
[백준/BOJ] 9328 열쇠 - JAVA
LIRI
2024. 8. 22. 22:35
백준 BOJ 9328 열쇠 - JAVA
수정중
[9328번: 열쇠
상근이는 1층 빌딩에 침입해 매우 중요한 문서를 훔쳐오려고 한다. 상근이가 가지고 있는 평면도에는 문서의 위치가 모두 나타나 있다. 빌딩의 문은 모두 잠겨있기 때문에, 문을 열려면 열쇠가
www.acmicpc.net](https://www.acmicpc.net/problem/9328)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Pos {
private int r;
private int c;
public Pos(int r, int c) {
this.r = r;
this.c = c;
}
public int getR() {
return r;
}
public int getC() {
return c;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st;
int T = Integer.parseInt(br.readLine());
for (int tc = 0; tc < T; tc++) {
// 입력
st = new StringTokenizer(br.readLine());
int h = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
char[][] map = new char[h + 1][w + 1];
Queue<Pos> queue = new ArrayDeque<>();
for (int r = 1; r <= h; r++) {
String line = br.readLine();
for (int c = 1; c <= w; c++) {
map[r][c] = line.charAt(c - 1);
if (map[r][c] != '*') {
if (r == 1 || r == h || c == 1 || c == w) {
queue.add(new Pos(r, c));
}
}
}
}
int key = 0;
String keyList = br.readLine();
if (!keyList.equals("0")) {
int keyNum = keyList.length();
for (int i = 0; i < keyNum; i++) {
key = key | (1 << (keyList.charAt(i) - 'a'));
}
}
int answer = 0;
// bfs
int[][] dr = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
Map<Character, List<Pos>> doorMap = new HashMap<>();
boolean[][] visited = new boolean[h + 1][w + 1];
while (!queue.isEmpty()) {
Pos now = queue.poll();
int nowR = now.getR();
int nowC = now.getC();
if (map[nowR][nowC] == '.') {
visited[nowR][nowC] = true;
} else if (map[nowR][nowC] == '$') {
answer++;
visited[nowR][nowC] = true;
map[nowR][nowC] = '.';
} else if (Character.isUpperCase(map[nowR][nowC])) { // 문
int door = 1 << (map[nowR][nowC] - 'A');
if ((door & key) > 0) { //열쇠 있음
visited[nowR][nowC] = true;
map[nowR][nowC] = '.';
} else { //열쇠 없음
List<Pos> doorList = new ArrayList<>();
if (doorMap.containsKey(map[nowR][nowC])) {
doorList = doorMap.get(map[nowR][nowC]);
}
doorList.add(new Pos(nowR, nowC));
doorMap.put(map[nowR][nowC], doorList);
continue;
}
} else { //열쇠
visited[nowR][nowC] = true;
char matchDoor = Character.toUpperCase(map[nowR][nowC]);
if (doorMap.containsKey(matchDoor)) {
List<Pos> doorList = doorMap.get(matchDoor);
queue.addAll(doorList);
doorMap.remove(matchDoor);
}
key = key | (1 << (map[nowR][nowC] - 'a'));
}
for (int[] d : dr) {
int nextR = nowR + d[0];
int nextC = nowC + d[1];
if (nextR < 1 || nextR > h || nextC < 1 || nextC > w) {
continue;
}
if (map[nextR][nextC] == '*' || visited[nextR][nextC]) {
continue;
}
queue.add(new Pos(nextR, nextC));
}
}
sb.append(answer).append("\n");
}
System.out.println(sb);
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Pos {
private int r;
private int c;
public Pos(int r, int c) {
this.r = r;
this.c = c;
}
public int getR() {
return r;
}
public int getC() {
return c;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st;
int T = Integer.parseInt(br.readLine());
for (int tc = 0; tc < T; tc++) {
// 입력
st = new StringTokenizer(br.readLine());
int h = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
char[][] map = new char[h + 1][w + 1];
Queue<Pos> queue = new ArrayDeque<>();
boolean[][] visited = new boolean[h + 1][w + 1];
for (int r = 1; r <= h; r++) {
String line = br.readLine();
for (int c = 1; c <= w; c++) {
map[r][c] = line.charAt(c - 1);
if (map[r][c] != '*') {
if (r == 1 || r == h || c == 1 || c == w) {
queue.add(new Pos(r, c));
visited[r][c] = true;
}
}
}
}
int key = 0;
String keyList = br.readLine();
if (!keyList.equals("0")) {
int keyNum = keyList.length();
for (int i = 0; i < keyNum; i++) {
key = key | (1 << (keyList.charAt(i) - 'a'));
}
}
int answer = 0;
// bfs
int[][] dr = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
List<Pos>[] doorArr = new List[26];
for (int i = 0; i < 26; i++) {
doorArr[i] = new ArrayList<>();
}
while (!queue.isEmpty()) {
Pos now = queue.poll();
int nowR = now.getR();
int nowC = now.getC();
if (map[nowR][nowC] == '.') {
} else if (map[nowR][nowC] == '$') {
answer++;
map[nowR][nowC] = '.';
} else if (map[nowR][nowC] >= 'A' && map[nowR][nowC] <= 'Z') { // 문
int doorNum = map[nowR][nowC] - 'A';
int door = 1 << doorNum;
if ((door & key) > 0) { //열쇠 있음
map[nowR][nowC] = '.';
} else { //열쇠 없음
doorArr[doorNum].add(new Pos(nowR, nowC));
continue;
}
} else { //열쇠
int door = map[nowR][nowC] - 'a';
queue.addAll(doorArr[door]);
doorArr[door] = new ArrayList<>();
key = key | (1 << (map[nowR][nowC] - 'a'));
}
for (int[] d : dr) {
int nextR = nowR + d[0];
int nextC = nowC + d[1];
if (nextR < 1 || nextR > h || nextC < 1 || nextC > w) {
continue;
}
if (map[nextR][nextC] == '*' || visited[nextR][nextC]) {
continue;
}
queue.add(new Pos(nextR, nextC));
visited[nextR][nextC] = true;
}
}
sb.append(answer).append("\n");
}
System.out.println(sb);
}
}
수정중
728x90