- 11967 불켜기 문제의 상위 호완 문제
불켜기 문제를 해결한 입장에서 99% 풀이를 수행
1% 오점: 열쇠를 주웠을 때, 잠금을 해재하는 방의 범위는 가장자리에서 침입 가능한 점을 기억해둬야 함
- sol: 잠금 해제 BFS
#include<bits/stdc++.h>
using namespace std;
int T, h, w, ans = 0;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
vector<string> board;
vector<vector<bool>> visited(101, vector<bool>(101, false));
deque<pair<int, int>> doorpos[26];
bool is_connected(int x, int y){
for(int i = 0; i < 4; ++i){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx < -1 || ny < -1 || nx > h || ny > w) continue;
if(visited[nx][ny] || nx == 0 || ny == 0 || nx == h || ny == w) return true;
}
return false;
}
void bfs(int x, int y){
queue<pair<int, int>> que;
visited[x][y] = true;
que.push({x, y});
while(!que.empty()){
auto cur = que.front();
que.pop();
if(board[cur.first][cur.second] == '$'){
++ans;
}
else if(islower(board[cur.first][cur.second])){
auto& vtmp = doorpos[board[cur.first][cur.second] - 'a'];
while(!vtmp.empty()){
auto tmp = vtmp.front();
if(is_connected(tmp.first, tmp.second)){
visited[tmp.first][tmp.second] = true;
que.push({tmp.first, tmp.second});
}
vtmp.pop_front();
board[tmp.first][tmp.second] = '.';
}
}
else if(isupper(board[cur.first][cur.second])){
visited[cur.first][cur.second] = false;
continue;
}
for(int i = 0; i < 4; ++i){
int nx = cur.first + dx[i];
int ny = cur.second + dy[i];
if(nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
if(visited[nx][ny] || board[nx][ny] == '*') continue;
visited[nx][ny] = true;
que.push({nx, ny});
}
}
return;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> T;
string tmp;
while(T--){
board.clear();
for(int i = 0; i < 26; ++i){
while(!doorpos[i].empty()){
doorpos[i].pop_front();
}
}
for(int i = 0; i < visited.size(); ++i)
for(int j = 0; j < visited[i].size(); ++j)
visited[i][j] = false;
ans = 0;
cin >> h >> w;
for(int i = 0; i < h; ++i){
cin >> tmp;
board.push_back(tmp);
for(int j = 0; j < tmp.size(); ++j){
if(isupper(tmp[j])){
doorpos[tmp[j]-'A'].push_back({i, j});
}
}
}
cin >> tmp;
if(tmp != "0"){
for(auto c : tmp){
while(!doorpos[c - 'a'].empty()){
auto fr = doorpos[c - 'a'].front();
board[fr.first][fr.second] = '.';
doorpos[c - 'a'].pop_front();
}
}
}
for(int i = 0; i < h; ++i){
for(int j = 0; j < w; ++j){
if(!(i == 0 || j == 0 || i == h-1 || j == w-1)) continue;
if(!visited[i][j] && board[i][j] != '*') bfs(i, j);
}
}
cout << ans << '\n';
}
return 0;
}