본문 바로가기
Problem Solving/백준

[백준] 7569번 : 토마토

by shinbian11 2020. 8. 22.

https://www.acmicpc.net/problem/7569

 

7569번: 토마토

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

www.acmicpc.net


//C++

#include <bits/stdc++.h>
#define F_I ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

using namespace std;
typedef long long ll;

int m, n, h, notomato = 0;

int dir[6][3] = { {0,1,0},{0,-1,0},{1,0,0},{-1,0,0},{0,0,1},{0,0,-1} };
int arr[104][104][104];

queue< pair<pair<int, int>, int> > q;

int isinside(int y, int x, int z) // next_x, next_y,next_z 가 arr 범위를 넘어가는지의 여부를 체크하는 함수
{
	if (x >= 0 && x < m && y >= 0 && y < n && z >= 0 && z < h)
		return 1;
	else
		return 0;
}

int allRipe() //현재 토마토가 모두 익었는지 판단하는 함수
{
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < n; j++)
		{
			for (int k = 0; k < m; k++)
			{
				if (arr[j][k][i] == 0)
					return 0;
			}
		}
	}
	return 1;
}

int BFS()
{
	int day = 0;
	if (q.empty()) //처음부터 익힐 수 있는 토마토가 없다면 -1 출력
	{
		return -1;
	}
	while (!q.empty())
	{
		int currentSize = q.size();
		for (int i = 0; i < currentSize; i++)
		{
			int x = q.front().first.first;
			int y = q.front().first.second;
			int z = q.front().second;
			q.pop();
			for (int i = 0; i < 6; i++)
			{
				int next_x = x + dir[i][0];
				int next_y = y + dir[i][1];
				int next_z = z + dir[i][2];
				if (isinside(next_x, next_y, next_z) && arr[next_x][next_y][next_z] == 0)
				{
					arr[next_x][next_y][next_z] = 1;
					q.push(make_pair(make_pair(next_x, next_y), next_z));
				}
			}
			if (q.size() == 0 && allRipe() == 1) //일단 익힐 수 있는 토마토를 모두 익혔고, 전체가 모두 익었다면 날짜 수 출력
				return day;
			else if (q.size() == 0 && allRipe() == 0) //일단 익힐 수 있는 토마토를 모두 익혔는데, 안 익은 토마토가 존재한다면 -1 출력
				return -1;
		}
		
		day++; //반복문이 한번 끝날때마다 day는 하루씩 증가
	}
	
}

int main()
{

	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 >> arr[j][k][i];
				if (arr[j][k][i] == -1) //토마토가 없는 곳의 개수 체크
					notomato++;
			}
		}
	}
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < n; j++)
		{
			for (int k = 0; k < m; k++)
			{
				if (arr[j][k][i] == 1)
				{
					q.push(make_pair(make_pair(j,k),i));
				}
			}
		}
	}
    //저장될 때부터 모든 토마토가 익어있는 상태이면 0을 출력해야 됨! 
	if (q.size() == m * n * h - notomato) 
	{
		cout << 0 << '\n';
	}
	else
	{
		cout << BFS() << '\n';
	}
	

	return 0;
}

 

> 주석에 설명을 모두 달아놓았습니다.