9328번: 열쇠
import org.w3c.dom.Node;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static class Position{
int x,y;
public Position(int x, int y){
this.x = x;
this.y = y;
}
}
static int n,m;
static char[][] board;
static boolean[] key;
static int[] dirx = {1,-1,0,0};
static int[] diry = {0,0,1,-1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
while(t>0){
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
board = new char[n+2][m+2];
key = new boolean[26];
String tmp = "";
for(int i = 0; i<n+2; i++){
if(i!=0 && i!=n+1) tmp = br.readLine();
for(int j = 0; j<m+2; j++){
if(i==0 || i==n+1) board[i][j] = '.';
else if(j == 0 || j==m+1) board[i][j] = '.';
else board[i][j] = tmp.charAt(j-1);
}
}
tmp = br.readLine();
for(int i = 0; i<tmp.length(); i++){
if(tmp.charAt(i) == '0') break;
key[tmp.charAt(i) - 'a'] = true;
}
System.out.println(bfs(0,0));
t--;
}
}
public static int bfs(int a, int b){
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{a,b});
boolean[][] visited = new boolean[n+2][m+2];
visited[a][b] = true;
int document = 0;
ArrayList<Position>[] door = new ArrayList[26];
for(int i = 0; i<26; i++){
door[i] = new ArrayList<>();
}
while(!queue.isEmpty()){
int[] cur = queue.poll();
int x = cur[0];
int y = cur[1];
for(int i = 0; i<4; i++){
int nx = x + dirx[i];
int ny = y + diry[i];
if(nx<0 || ny<0 || nx>=n+2 || ny>=m+2) continue;
if(board[nx][ny] == '*' || visited[nx][ny]) continue;
int doorCheck = board[nx][ny] - 'A';
int keyCheck = board[nx][ny] - 'a';
visited[nx][ny] = true;
if(board[nx][ny] == '.') queue.add(new int[]{nx,ny});
else if(board[nx][ny] == '$'){
queue.add(new int[]{nx,ny});
// System.out.println(nx + ", " + ny + "에 있는 문서를 훔쳤지롱");
document ++;
}
else if(doorCheck>=0 && doorCheck<=25){
if(key[doorCheck]) queue.add(new int[]{nx, ny});
else{
// System.out.println(nx + ", " + ny + "에서 열쇠가 없어서 대기중 ㅠㅠ" + doorCheck);
door[doorCheck].add(new Position(nx, ny));
}
}
else if(keyCheck>=0 && keyCheck<=25){
key[keyCheck] = true;
// System.out.println(keyCheck + "의 키를 얻어서 " + door[keyCheck].size() + "개의 문을 연다!");
queue.add(new int[]{nx, ny});
for(int j = 0; j<door[keyCheck].size();){
Position tmp = door[keyCheck].get(j);
int tmpx = tmp.x;
int tmpy = tmp.y;
// System.out.println(tmpx + ", " + tmpy + " : 문이 열렸다!");
queue.add(new int[]{tmpx, tmpy});
door[keyCheck].remove(tmp);
}
}
}
}
return document;
}
}