예전에 bfs 입문 당시 풀었던 토마토 문제의 3차원 버전이다.
2차원 버전 문제 내용이 정확히 기억은 안나지만 같은 로직을 3차원으로 확장하면 될 거 같다.
접근은 bfs를 돌려주되 모든 1인 지점을 다 queue에 넣어두고 시작하면 된다
문제 풀면서 하나 배운 점이 있었는데 3차원 좌표를 queue에 저장하고 사용할 때
queue<pair<int, pair<int, int>>> q;
q.push({z, {y, x}});
auto [z, yx] = q.top();
auto [y, x] = yx;
이런 식으로 작성했었는데 pair 대신 tuple을 사용하면
queue<tuple<int, int, int>> q;
q.push({z, y, x});
auto [z, y, x] =q.top();
으로 간편하게 코드를 작성할 수 있엇다.
깨달음을 주신 malkoring 형 감사합니다:D
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int m, n, h;
int board[100][100][100];
int ret = INT_MAX;
int dx[] = {1, -1, 0, 0, 0, 0};
int dy[] = {0, 0, 1, -1, 0, 0};
int dz[] = {0, 0, 0, 0, 1, -1};
bool InRange(int z, int y, int x) {
if (0 <= z && z < h)
if (0 <= y && y < n)
if (0 <= x && x < m)
return true;
return false;
}
int Bfs() {
queue<tuple<int, int, int, int>> q;
for (int i = 0; i < h; ++i)
for (int j = 0; j < n; ++j)
for (int k = 0; k < m; ++k)
if (board[i][j][k] == 1)
q.push({i, j, k, 1});
while (!q.empty()) {
auto [nz, ny, nx, ns] = q.front();
q.pop();
for (int i = 0; i < 6; ++i) {
int nextZ = nz + dz[i], nextY = ny + dy[i], nextX = nx + dx[i], nextS = ns + 1;
if (!InRange(nextZ, nextY, nextX)) continue;
if (board[nextZ][nextY][nextX] == 0) {
board[nextZ][nextY][nextX] = nextS;
q.push({nextZ, nextY, nextX, nextS});
}
}
}
bool flag = true;
int ret = 0;
for (int i = 0; i < h; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < m; ++k) {
if (board[i][j][k] == 0) flag = false;
ret = max(ret, board[i][j][k]);
}
}
}
if (flag) return ret - 1;
else return -1;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >>m >> n >> h;
for (int i = 0; i < h; ++i)
for (int j = 0; j < n; ++j)
for (int k = 0; k < m; ++k)
cin >> board[i][j][k];
cout << Bfs() << '\n';
}