본문 바로가기
Algorithm/BOJ

[BOJ]7576번: 토마토 (c++)

by HBGB 2020. 5. 28.

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

 

7576번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토�

www.acmicpc.net

 

 

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

int bfs(vector<vector<int>>& box, queue<pair<int, int>>& q, int N, int M, int left)
{
	// 안익은 토마토가 없다면
	if (left == 0)
	{
		return 0;
	}

	int dir_x[4] = { 0, 1, 0, -1 };
	int dir_y[4] = { 1, 0, -1, 0 };
	int max_d = 0;

	while (!q.empty())
	{
		int x = q.front().first;
		int y = q.front().second;
		q.pop();
		--left;

		// 모든 토마토가 익을 때까지 걸리는 일수 구하기
		max_d = (max_d < box[x][y]) ? box[x][y] : max_d;

		// 4방향 탐색
		for (int i = 0; i < 4; ++i)
		{
			int new_x = x + dir_x[i];
			int new_y = y + dir_y[i];

			// 닿을 수 없는 위치일 때
			if (new_x < 0 || new_x >= N || new_y < 0 || new_y >= M)
			{
				continue;
			}

			// 아직 익지 않은 토마토는 큐에 push하고 값을 현재 위치의 값 + 1
			if (box[new_x][new_y] == 0)
			{
				q.push({new_x, new_y});
				box[new_x][new_y] = box[x][y] + 1;
			}
		}
	}

	return (left > 0) ? -1 : max_d - 1;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	// 입력
	int M, N;
	cin >> M >> N;
	vector<vector<int>> box(N, vector<int>(M));
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < M; ++j)
		{
			cin >> box[i][j];
		}
	}

	queue<pair<int, int>> q;
	int left = M * N;
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < M; ++j)
		{
			// 익은 토마토는 큐에 push
			if (box[i][j] == 1)
			{
				q.push({ i, j });
			}
			// 토마토가 없으면 left - 1
			else if (box[i][j] == -1)
			{
				--left;
			}
		}
	}

	/*
		너비우선 탐색으로
		익히는게 가능한 토마토가 모두 익기까지의 최소 일수 구하기
	*/
	cout << bfs(box, q, N, M, left);

	return 0;
}

 

 

TIP1

미로 탐색 문제와 마찬가지로, 상자의 모든 토마토가 익기까지의 최소 날짜를 구하는 문제이다. 

단, 차이점은 이번에는 시작점이 2개 이상이 될수도 있고

어느 위치에서든 시작할수 있다는 점이다.

 

따라서 처음에 상자 전체를 탐색하며

토마토가 들어있는 위치값을 큐에 넣어주어야 한다.

for (int i = 0; i < N; ++i)
{
    for (int j = 0; j < M; ++j)
    {
        // 익은 토마토는 큐에 push
        if (box[i][j] == 1)
        {
            q.push({ i, j });
        }
        ...

 

 

TIP2

예외처리도 신경써주도록 하자.

1. 안익은 토마토가 하나도 없을 때

2. 도달하지 못하는 곳이 있을 때

 

bfs함수 내에서 처리하는게 깔끔하다.

'Algorithm > BOJ' 카테고리의 다른 글

[BOJ]16929번: Two Dots (c++)  (0) 2020.05.28
[BOJ]7562번: 나이트의 이동 (c++)  (0) 2020.05.28
[BOJ]2178번: 미로 탐색 (c++)  (0) 2020.05.28
[BOJ]4963번: 섬의 개수 (c++)  (0) 2020.05.28
[BOJ]2667번: 단지번호붙이기 (c++)  (0) 2020.05.28

댓글