Algorithm/그래프
백준 7569 토마토
쩡류
2021. 12. 4. 17:38
728x90
https://www.acmicpc.net/problem/7569
7569번: 토마토
첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,
www.acmicpc.net
- 그래프 탐색 문제인데, 특이하게도 3차원으로 값이 주어져서 난이도가 조금 올라가는 문제이다. 따라서, 필자는 3차원 배열을 활용하였고 M,N,H를 각각 X,Y,Z로 두어서 계산을 하였다.(각각 행, 열, 높이)
- 시간복잡도는 O(MNH)이 나온다. 2차원 그래프탐색을 H번 진행해야 하므로!
- 처음에 토마토가 담긴 칸을 queue에 담는다. 또, visited를 0으로 설정한다. queue는 2개의 pair가 존재하는데, 1개는 높이와 x좌표, 다른 하나는 y좌표와 해당 칸의 방문 시간을 의미한다.
- visited 배열은 해당 칸의 토마토가 익는 최소 시간값을 담는다. 해당 칸이 벽이거나, 처음부터 익은 토마토인 경우 0이 담긴다.
또, BFS를 진행할 때 큐에 담기지 않는 조건은
1. 범위를 벗어날 때
2. 만약 이미 토마토가 익은 시간이 담겨져 있을 때, 최신화하려는 값이 기존의 시간보다 더 크거나 같은 경우
3. 벽일때(-1일때)
로 잡는다.
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int tomato[101][101][101];
int visited[101][101][101];
int m,n,h;
int dz[] = { 0,0,0,0,1,-1 };
int dx[] = { 0,0,1,-1,0,0 };
int dy[] = { -1,1,0,0,0,0 };
int answer;
queue<pair<pair<int, int>, pair<int, int>>> q;
void BFS() {
while (!q.empty()) {
int z = q.front().first.first;
int x = q.front().first.second;
int y = q.front().second.first;
int time = q.front().second.second;
q.pop();
for (int k = 0; k < 6; k++) {
int nz = z + dz[k]; int nx = x + dx[k]; int ny = y + dy[k];
if (nz < 0 || nz >= h || nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if (tomato[nz][nx][ny] == -1) continue;
if (tomato[nz][nx][ny] == 1 && time + 1 >= visited[nz][ny][nx]) continue;
visited[nz][nx][ny] = time + 1;
tomato[nz][nx][ny] = 1;
q.push({{ nz,nx }, { ny,time + 1 }});
}
}
}
int main() {
cin >> m >> n >> h;
int num_of_green = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < m; k++) {
cin >> tomato[i][j][k];
if (tomato[i][j][k] == 1) {
q.push({ {i,j}, {k,0} });
};
if (tomato[i][j][k] == 0) num_of_green++;
}
}
}
if (num_of_green == m * n * h) answer = -1;
else BFS();
for (int i = 0; i < h; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < m; k++) {
if (visited[i][j][k] == 0 && tomato[i][j][k] == 0) {
cout << -1;
return 0;
}
answer = max(answer, visited[i][j][k]);
}
}
}
cout << answer;
return 0;
}