득이공간

[백준 C++] 7569 토마토 - 너비우선탐색 본문

PS/알고리즘 문제풀이

[백준 C++] 7569 토마토 - 너비우선탐색

쟁득 2024. 2. 17. 22:53
 

7569번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,

www.acmicpc.net

cpp
#include <iostream> #include <queue> #include <tuple> using namespace std; typedef tuple<int, int, int> Coord; int Box[100][100][100]; int Day[100][100][100]; int M, N, H; int DX[6] = { -1, 1, 0, 0, 0, 0 }; // Left, Right int DY[6] = { 0, 0, -1, 1, 0, 0 }; // Top, Bottom int DZ[6] = { 0, 0, 0, 0, -1, 1 }; // Down, Up queue<Coord> SearchQueue; int CountDays() { int MaxDay = 0; // Binary First Search while (!SearchQueue.empty()) { ‌‌int X = get<0>(SearchQueue.front()); ‌‌int Y = get<1>(SearchQueue.front()); ‌‌int Z = get<2>(SearchQueue.front()); ‌‌SearchQueue.pop(); ‌‌if (Box[Z][Y][X] == -1) ‌‌{ ‌‌‌continue; ‌‌} ‌‌Box[Z][Y][X] = -1; ‌‌for (int i = 0; i < 6; ++i) ‌‌{ ‌‌‌int NX = X + DX[i]; ‌‌‌int NY = Y + DY[i]; ‌‌‌int NZ = Z + DZ[i]; ‌‌‌if (NX < 0 || NX > M - 1 ‌‌‌‌|| NY < 0 || NY > N - 1 ‌‌‌‌|| NZ < 0 || NZ > H - 1 ‌‌‌‌|| Box[NZ][NY][NX] == -1) ‌‌‌{ ‌‌‌‌continue; ‌‌‌} ‌‌‌if (Box[NZ][NY][NX] == 0) ‌‌‌{ ‌‌‌‌Box[NZ][NY][NX] = 1; ‌‌‌‌int NewDay = Day[Z][Y][X] + 1; ‌‌‌‌Day[NZ][NY][NX] = NewDay; ‌‌‌‌if (NewDay > MaxDay) ‌‌‌‌{ ‌‌‌‌‌MaxDay = NewDay; ‌‌‌‌} ‌‌‌} ‌‌‌SearchQueue.emplace(NX, NY, NZ); ‌‌} } for (int i = 0; i < H; ++i) { ‌‌for (int j = 0; j < N; ++j) ‌‌{ ‌‌‌for (int k = 0; k < M; ++k) ‌‌‌{ ‌‌‌‌if (Box[i][j][k] == 0) ‌‌‌‌{ ‌‌‌‌‌return -1; ‌‌‌‌} ‌‌‌} ‌‌} } return MaxDay; } int main() { ‌ios::sync_with_stdio(false); ‌cin.tie(NULL); cout.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 >> Box[i][j][k]; ‌‌‌‌if (Box[i][j][k] == 1) ‌‌‌‌{ ‌‌‌‌‌SearchQueue.emplace(k, j, i); ‌‌‌‌} ‌‌‌} ‌‌} } ‌cout << CountDays(); }

 

3차원 공간에서 너비 우선 탐색을 이용해서 푸는 문제입니다.

풀이 과정은 다음과 같습니다.

 

1. 입력 받은 토마토 정보 box 배열에 저장 - 처음부터 익은 토마토는 BFS 큐에 추가

2. 각 토마토가 몇번째 날에 익었는지 정보를 담는 day 배열 모두 0 값으로 초기화

3. 큐에 담긴 토마토부터 너비 우선 탐색 시작

4. 익지 않은 인접 토마토에 현재 토마토 날짜 + 1 날짜 값 저장 - 이 때 현재까지 증가된 날짜 중 최대값은 따로 저장

5. 탐색을 마친 후, 저장해놓은 날짜 최대값 출력 - 예외처리: 익지 않은 토마토가 존재하면 -1 출력