반응형
먼저 모서리 부분들을 계속 돌면서, 빌딩에 진입할 수 있는 위치를 찾아줬습니다.
여기서 주의할 점은 빌딩 진입 부분에는 빈공간과 문, 벽 외에도 문서나 열쇠가 올 수도 있었습니다.
따라서 모서리 부분에서 열쇠를 새로이 습득하는 상황이라면, 모서리 부분을 계속해서 재탐색해주었습니다.
빌딩에 진입하면, BFS를 돌며 열쇠와 문서를 탐색합니다.
열쇠를 습득한다면, 큐를 다 비워주고, 그 위치에서부터 다시 탐색을 수행하였습니다.
한번 찾은 문서는 중복 카운트를 방지하기 위해 빈 공간으로 바꿔주었습니다.
#include <iostream>
#include <queue>
#include <cstring>
#define INF 987654321
using namespace std;
int t, h, w, ans = 0, f;
char map[100][101], temp[27];
bool visit[100][100];
bool keys[26] = { false };
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };
void bfs(int sx, int sy) {
if (map[sx][sy] == '*') return;
if (('A' <= map[sx][sy] && map[sx][sy] <= 'Z') && !keys[map[sx][sy] - 'A']) return;
if (visit[sx][sy]) return;
int cnt = 0;
queue<pair<int, int>> q;
q.push({ sx, sy });
visit[sx][sy] = true;
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
if (map[x][y] == '$') map[x][y] = '.', cnt++;
if ('a' <= map[x][y] && map[x][y] <= 'z' && !keys[map[x][y] - 'a']) {
// 열쇠 찾음
f = 0;
keys[map[x][y] - 'a'] = true;
while (!q.empty()) q.pop(); // 큐를 다 비워주고 현재 위치에서부터 재탐색
memset(visit, false, sizeof(visit));
visit[x][y] = true;
q.push({ x, y });
continue;
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
if (visit[nx][ny]) continue;
if (map[nx][ny] == '*') continue;
if ('A' <= map[nx][ny] && map[nx][ny] <= 'Z' && !keys[map[nx][ny] - 'A'])
continue; // 열쇠 없으면 이동 못함
visit[nx][ny] = true;
q.push({ nx, ny });
}
}
ans += cnt;
}
void startPoint(int flag) { // 빌딩 진입 위치 탐색. 상하좌우 모서리.
if (flag == 0)
for (int i = 0; i < w; i++) bfs(0, i);
else if (flag == 1)
for (int i = 0; i < w; i++) bfs(h - 1, i);
else if (flag == 2)
for (int i = 1; i < h - 1; i++) bfs(i, 0);
else
for (int i = 1; i < h - 1; i++) bfs(i, w - 1);
}
int main() {
scanf("%d", &t);
while (t-- && scanf("%d %d", &h, &w)) {
ans = 0;
memset(keys, false, sizeof(keys));
memset(visit, false, sizeof(visit));
for (int i = 0; i < h; i++) scanf("%s", map[i]);
scanf("%s", temp);
if (temp[0] != '0') // 열쇠 등록
for (int i = 0; i < strlen(temp); i++) keys[temp[i] - 'a'] = true;
while (1) {
f = 1;
for (int i = 0; i < 4; i++) startPoint(i);
if (f) break; // 열쇠를 새로이 찾은 상황이라면 재탐색
}
printf("%d\n", ans);
}
}
반응형
'Algorithm' 카테고리의 다른 글
백준 2696 : 중앙값 구하기 (0) | 2021.11.12 |
---|---|
백준 9376 : 탈옥 (0) | 2021.11.12 |
백준 4991 : 로봇 청소기 (0) | 2021.11.12 |
백준 6087 : 레이저 통신 (0) | 2021.11.12 |
백준 15558 : 점프 게임 (0) | 2021.11.12 |