백준 7576_토마토 문제풀이 in C++
문제 URL
https://www.acmicpc.net/problem/7576
문제 요구사항
- 하루에 한 칸씩 익은 토마토들의 영향이 전이되어 익지 않은 토마토들이 익게 된다.
- 이때, 모든 토마토가 익게 되는 최소한의 시간을 구하여라.
- 첫번째 줄에는 토마토 상자 크기가 주어진다. (M, N)
- 이어서 토마토 맵의 값이 주어진다.
- -1은 토마토가 안 들어있는 칸
- 0은 익지 않은 토마토가 들어있는 칸
- 1은 익은 토마토가 들어있는 칸
접근 방법
- ‘여러 군데에 익은 토마토가 있을 시 어떻게 접근해야 하는가?’를 해결하면 이 문제를 풀 수 있게 된다. 해당 문제는 칸 입력 시 1일 때, 그 좌표 값을 큐에 넣어 BFS 반복 좌표를 해당 좌표로 선정한다. 또, 미로 탐색(최소 이동)과 비슷하게 풀이하면 되는데 해당 문제는 이동 할 수 있는(덜 익은 토마토가 있는) 모든 칸을 이동하는데 걸리는 시간을 구하면 된다. 즉, 모든 칸을 가면 되기 때문에 Check를 굳이 할 필요가 없다.
풀이 순서
- 토마토 맵 입력 시 1인 경우(익은 토마토인 경우) 해당 좌표를 큐에 넣는다.
- BFS 함수 작성 시 다음 칸이 이동 가능하면 현재 자리 값에 + 1 한 값을 다음 칸에 대입한다.
- 이렇게 만들어진 토마토 맵을 다시 반복문을 이용해서 탐색한다. 이때, 0이 하나라도 존재하면 -1을 출력하고 프로그램 종료, 아니라면 result 값과 맵의 각 값을 비교하며 최대로 큰 값을 대입한다.
소스코드
#include <iostream>
#include <queue>
using namespace std;
int tomatoMap[1000][1000];
queue<pair<int, int>> q;
int result = 0;
int M, N;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
void tomatoBFS() {
while (!q.empty()) {
int xx = q.front().first;
int yy = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int nx = xx + dx[i];
int ny = yy + dy[i];
if (nx >= 0 && ny >= 0 && nx < N && ny < M) {
if (tomatoMap[nx][ny] == 0) {
tomatoMap[nx][ny] = tomatoMap[xx][yy] + 1;
q.push(make_pair(nx, ny));
}
}
}
}
}
void tomato() {
cin >> M >> N;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
cin >> tomatoMap[i][j];
if (tomatoMap[i][j] == 1) {
q.push(make_pair(i, j));
}
}
}
tomatoBFS();
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (tomatoMap[i][j] == 0) {
cout << -1 << "\n";
return;
}
if (result < tomatoMap[i][j]) {
result = tomatoMap[i][j];
}
}
}
cout << result - 1 << "\n";
}
int main() {
tomato();
return 0;
}