ps
[백준] 9328 - 열쇠
kariskan
2022. 7. 27. 20:29
https://www.acmicpc.net/problem/9328
9328번: 열쇠
상근이는 1층 빌딩에 침입해 매우 중요한 문서를 훔쳐오려고 한다. 상근이가 가지고 있는 평면도에는 문서의 위치가 모두 나타나 있다. 빌딩의 문은 모두 잠겨있기 때문에, 문을 열려면 열쇠가
www.acmicpc.net
이 문제는 두 가지로 나누어져 있다.
- 입구를 찾는 문제
- 열쇠를 찾으며 문서를 얻는 문제
입구를 찾는 문제는 주어진 입력에 빈 공간(.)으로 이루어진 테두리를 두르는 형태로 구현하였다.
그래서 그 테두리 중 어느곳에서 시작하여도 입구를 찾아서 진행할 수 있다.
다음으로 열쇠를 찾으며 문서를 얻는 문제이다.
기본적인 BFS와는 달리, 열쇠를 얻어야만 갈 수 있는 곳이 생기기 때문에 똑같은 곳을 한 번 이상 방문할 수도 있다.
따라서 기존 BFS에서 열쇠를 얻으면 방문 배열을 초기화한 후에 계속 진행하도록 했다.
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
int t, n, m, key[26], visit[102][102];
int x[4] = { 0,0,1,-1 };
int y[4] = { 1,-1,0,0 };
char map[102][102];
string q;
int main() {
cin >> t;
while (t--) {
cin >> n >> m;
for (int i = 0; i < n + 2; i++) {
for (int j = 0; j < m + 2; j++) {
if (i == 0 || i == n + 1 || j == 0 || j == m + 1) {
map[i][j] = '.';
}
else {
cin >> map[i][j];
}
}
}
cin >> q;
for (char& c : q)key[c - 'a'] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (map[i][j] >= 'A' && map[i][j] <= 'Z' && key[map[i][j] - 'A'])map[i][j] = '.';
}
}
int ans = 0;
queue<pair<int, int>> q;
q.push({ 0,0 });
visit[0][0] = 1;
while (!q.empty()) {
int a = q.front().first;
int b = q.front().second;
q.pop();
for (int k = 0; k < 4; k++) {
int nx = a + x[k];
int ny = b + y[k];
if (nx >= 0 && nx <= n + 1 && ny >= 0 && ny <= m + 1 &&
map[nx][ny] != '*' && !visit[nx][ny]) {
if (map[nx][ny] >= 'a' && map[nx][ny] <= 'z') {
key[map[nx][ny] - 'a'] = 1;
map[nx][ny] = '.';
while (!q.empty())q.pop();
memset(visit, 0, sizeof(visit));
q.push({ nx,ny });
visit[nx][ny] = 1;
}
else if (map[nx][ny] >= 'A' && map[nx][ny] <= 'Z' && key[map[nx][ny] - 'A']) {
map[nx][ny] = '.';
q.push({ nx,ny });
visit[nx][ny] = 1;
}
else if (map[nx][ny] == '$') {
map[nx][ny] = '.';
ans++;
q.push({ nx,ny });
visit[nx][ny] = 1;
}
else if (map[nx][ny] == '.') {
q.push({ nx,ny });
visit[nx][ny] = 1;
}
}
}
}
cout << ans << '\n';
memset(key, 0, sizeof(key));
memset(visit, 0, sizeof(visit));
memset(map, 0, sizeof(map));
}
}