3055. 탈출
2021-07-20
백준 3055번 풀이
이 글은 Obsidian에서 마이그레이션되었으며, 그 과정에서 AI의 도움을 받았습니다. 오류나 누락된 내용이 있다면 댓글로 알려주세요!
문제
풀이
아이디어
무언가 퍼지는 느낌이고 (여기서는 물이) 여러 방향으로 가는 무언가가 (여기서는 고슴도치가) 목적지에 도달할 수 있는 최단 시간을 구하는 것이기 때문에 어렵지 않게 BFS를 떠올릴 수 있었다. 최단시간만 구하는 문제였다면 DFS를 사용해도 되었겠지만 여기서는 물도 함께 퍼지기 때문에 DFS로는 풀지 못하거나 풀 수 있더라도 복잡한 방법이 될 것 같다.
문제를 확인해 보면 매 초마다 물이 4방향으로 퍼지고, 고슴도치가 4방향으로 움직일 수 있다. 물과 고슴도치의 움직임에 각각 BFS를 적용해서 물 먼저 움직인 후에, 고슴도치를 움직여주는 방법으로 문제를 해결했다. 물을 먼저 움직인 이유는 고슴도치가 움직일 방향에 물이 찰 예정인 경우 일때는 그 쪽으로 움직일 수 없다고 해서 처리의 용이성을 위해서 물을 먼저 이동시켜주었다. 사실 같은 BFS이기 때문에 큐를 하나만 두고 움직이는 방법도 있는 듯 한데… 큐를 두개 두는 편이 좀 더 이해하기 쉬운 것 같아서 그냥 2개 두는 방법만 생각해 보았다.
코드
#include <iostream>
#include <queue>
#include <utility>
#include <queue>
using namespace std;
//pair first: 행 second: 열
int cnt;
char map[50][50];
queue<pair<int, int>> s_queue; // s(고슴도치) 큐
queue<pair<int, int>> water; // 물 큐
int dy[] = {0, 1, 0, -1};
int dx[] = {1, 0, -1, 0};
int r, c;
void water_move(){
pair<int, int> curr;
pair<int, int> new_w;
int size = water.size();
for(int i = 0; i < size; i++){
curr = water.front();
water.pop();
for(int dir = 0; dir < 4; dir++){
new_w = {curr.first + dy[dir], curr.second + dx[dir]};
if(new_w.first < 0 || new_w.second < 0 || new_w.first > r || new_w.second > c || map[new_w.first][new_w.second] != '.')
continue;
map[new_w.first][new_w.second] = '*';
water.push(new_w);
}
}
}
void bfs(){
pair<int, int> curr_s;
pair<int, int> new_s;
while (!s_queue.empty()){
cnt++;
water_move();
int size = s_queue.size();
for (int i = 0; i < size; i++){
curr_s = s_queue.front();
s_queue.pop();
for(int dir = 0; dir < 4; dir++){
new_s = {curr_s.first + dy[dir], curr_s.second + dx[dir]};
if (map[new_s.first][new_s.second] == 'D'){
cout << cnt;
return;
}
if(new_s.first < 0 || new_s.second < 0 || new_s.first > r || new_s.second > c || map[new_s.first][new_s.second] != '.')
continue;
map[new_s.first][new_s.second] = '*';
s_queue.push(new_s);
}
}
}
cout << "KAKTUS";
return;
}
int main(){
cin >> r >> c;
cnt = 0;
for (int i = 0; i < r; i++){
for (int j = 0; j < c; j++){
cin >> map[i][j];
if (map[i][j] == 'S')
s_queue.push({i, j});
else if (map[i][j] == '*')
water.push({i, j});
}
}
bfs();
}