queue
를 2개 사용합니다.queue
에 들어있는 요소들에 대해 이동을 진행,queue
에 들어있는 요소들에 대해 이동을 진행,Tip: 의외로 범위 검사하는 코드가 횟수가 많아지면 꽤 큰 overhead가 됩니다. 이런 경우 저는 양사이드에 한 칸 씩을 더 만든 뒤 사용합니다. 이게 더 효율적이고 빠르더라구요.
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int d[4][2] = {{-1, 0}, {0, 1}, {0, -1}, {1, 0}};
int R, C, goalY, goalX;
bool visited[52][52];
char map[52][52];
queue<pair<int, int>> qWater, qMole;
int simulate() {
int tick = 0;
while (!qMole.empty()) {
// 먼저 현재 phase에서 물이 있는 칸을 이동시킨다.
int numWater = qWater.size();
while (numWater--) {
int cy = qWater.front().first, cx = qWater.front().second;
qWater.pop();
for (int i = 0; i < 4; ++i) {
int ny = cy + d[i][0], nx = cx + d[i][1];
// 물은 돌과 목적지를 지나갈 수 없다.
if (map[ny][nx] == '.') {
map[ny][nx] = '*';
qWater.push({ny, nx});
}
}
}
// 그 뒤 현재 phase에서 고슴도치가 있을 수 있는 칸을 이동시킨다.
int numMole = qMole.size();
while (numMole--) {
int cy = qMole.front().first, cx = qMole.front().second;
qMole.pop();
visited[cy][cx] = true;
if (cy == goalY && cx == goalX) return tick;
for (int i = 0; i < 4; ++i) {
int ny = cy + d[i][0], nx = cx + d[i][1];
// 고슴도치는 물과 돌을 지나갈 수 없다.
if (map[ny][nx] != 'X' && map[ny][nx] != '*'&& !visited[ny][nx]) {
visited[ny][nx] = true;
qMole.push({ny, nx});
}
}
}
tick++;
}
return -1;
}
int main() {
ios::sync_with_stdio(false), cin.tie(NULL);
cin >> R >> C;
memset(map, 'X', sizeof(map));
for (int y = 1; y <= R; ++y)
for (int x = 1; x <= C; ++x) {
cin >> map[y][x];
if (map[y][x] == 'D') goalY = y, goalX = x;
else if (map[y][x] == 'S') qMole.push({y, x});
else if (map[y][x] == '*') qWater.push({y, x});
}
int answer = simulate();
if (answer == -1) cout << "KAKTUS";
else cout << answer;
}