쾌락없는 책임 (공부)/알고리즘 문제풀이
[Algorithm] 백준 토마토 7569 - C++, BFS
허스크
2022. 5. 18. 15:11
반응형
7569번: 토마토
첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,
www.acmicpc.net
#include <iostream>
#include <queue>
using namespace std;
const int MAX = 101;
int m, n, h;
int totalTomato = 0;
int tomato[MAX][MAX][MAX];
int moveZ[] = { 0, 0, 0, 0, 1, -1 };
int moveY[] = { 1, -1, 0, 0, 0, 0 };
int moveX[] = { 0, 0, 1, -1, 0, 0 };
queue<pair<int, pair<int, int>>> q;
bool IsOut(int z, int y, int x){
if(z < 0 || y < 0 || x < 0 || z >= h || y >= n || x >= m)
return true;
return false;
}
int main(){
// init
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
// input
cin >> m >> n >> h;
for(int z = 0; z < h; z++){
for(int y = 0; y < n; y++){
for(int x = 0; x < m; x++){
int input;
cin >> input;
tomato[z][y][x] = input;
if(input == -1) continue;
if(input == 1){
q.push({z, {y, x}});
}
if(input == 0){
totalTomato++;
}
}
}
}
if(totalTomato == 0){
cout << "0\n";
return 0;
}
//
int makeCount = 0;
int dayCount = 0;
while (!q.empty()){
int curDay = q.size();
for(int day = 0; day < curDay; day++){
int curZ = q.front().first;
int curY = q.front().second.first;
int curX = q.front().second.second;
q.pop();
for(int i = 0; i < 6; i++){
int nextZ = curZ + moveZ[i];
int nextY = curY + moveY[i];
int nextX = curX + moveX[i];
if(IsOut(nextZ, nextY, nextX)) continue;
if(tomato[nextZ][nextY][nextX] != 0) continue;
tomato[nextZ][nextY][nextX] = 1;
q.push({nextZ, {nextY, nextX}});
makeCount++;
}
}
dayCount++;
}
if(makeCount == totalTomato)
cout << dayCount-1 << '\n';
else
cout << "-1\n";
return 0;
}
기존 2차원 배열의 토마토 BFS 문제에서 차원이 하나 더 생긴 문제입니다. 단 이번에는 다 익힐 수 있다면 날짜를 구해야하는 문제로 조금 더 생각할 부분이 있었습니다.
if(input == 1){
q.push({z, {y, x}});
}
if(input == 0){
totalTomato++;
}
input 에서 만일 익은 토마토라면 큐에 넣어주고 일반 토마토의 경우 갯수를 세 주었습니다. 계속 익은 정도를 확인하기에는 3차원에 최대 100 * 100 * 100 = 1000000을 탐색해야 하니 갯수를 미리 세 둬서 BFS가 끝났을 때 익힌 토마토 수와 익혀야 하는 토마토 수를 비교해 성공 여부를 판별할 생각입니다.
while (!q.empty()){
int curDay = q.size();
for(int day = 0; day < curDay; day++){
그리고 기존의 BFS 에서 날짜를 구하기 위해 현재 큐에 들어있는 토마토(오늘)을 구한뒤 이만큼 for문을 돌려 하루를 체크 했습니다.
if(totalTomato == 0){
cout << "0\n";
return 0;
}
// BFS...
if(makeCount == totalTomato)
cout << dayCount-1 << '\n';
else
cout << "-1\n";
출력의 경우 BFS 전 익혀야할 토마토가 없다면 0을 출력해주고 있다면 탐색 후 위에 말한대로 값을 비교해 날짜를 출력하거나 실패의 의미인 -1을 표기하도록 했습니다.
반응형