철수의 토마토 농장에서는 토마토를 보관하는 큰 창고를 가지고 있다.
토마토는 아래의 그림과 같이 격자 모양 상자의 칸에 하나씩 넣어서 창고에 보관한다.
창고에 보관되는 토마토들 중에는 잘 익은 것도 있지만, 아직 익지 않은 토마토들도 있을 수 있다.
보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다.
하나의 토마토의 인접한 곳은 왼쪽, 오른쪽, 앞, 뒤 네 방향에 있는 토마토를 의미한다.
대각선 방향에 있는 토마토들에게는 영향을 주지 못하며, 토마토가 혼자 저절로 익는 경우는 없다고 가정한다.
철수는 창고에 보관된 토마토들이 며칠이 지나면 다 익게 되는지, 그 최소 일수를 알고 싶어 한다.
토마토를 창고에 보관하는 격자모양의 상자들의 크기와 익은 토마토들과 익지 않은 토마토들의 정보가 주어졌을 때,
며칠이 지나면 토마토들이 모두 익는지, 그 최소 일수를 구하는 프로그램을 작성하라.
단, 상자의 일부 칸에는 토마토가 들어있지 않을 수도 있다.
#include <iostream>
#include <queue>
using namespace std;
int M, N;
int box[1001][1001];
int dist[1001][1001];
int dx[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0, 0 };
int main() {
cin >> M >> N;
queue<pair<int, int>> q;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
cin >> box[i][j];
dist[i][j] = -1;
if (box[i][j] == 1) {
q.push({ i, j });
dist[i][j] = 0;
}
}
}
while (!q.empty()) {
auto [cx, cy] = q.front();
q.pop();
for (int d = 0; d < 4; d++) {
int nx = cx + dx[d];
int ny = cy + dy[d];
if (nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
if (box[nx][ny] != 0) continue;
if (dist[nx][ny] != -1) continue;
dist[nx][ny] = dist[cx][cy] + 1;
box[nx][ny] = 1;
q.push({ nx, ny });
}
}
int answer = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (box[i][j] == 0) {
cout << -1 << "\n";
return 0;
}
if (dist[i][j] != -1) {
answer = max(answer, dist[i][j]);
}
}
}
cout << answer << "\n";
return 0;
}
box배열 에는 현재 창고의 토마토 상태를 저장한고
dist에는 토마토가 익기까지 걸린 일수를 저장
dx와 dy는 상하좌우 이동을 위한 변화량
그후 모든 칸의 일수를 -1로 초기화 한뒤 if문을 이용해서 처음 부터 익은 토마토는 시작점의 일수가 0이도록 한다
그후 while문을 이용하여 큐에서 익은 토마토를 꺼내어 상하좌우로 움직이며 상자의 범위에 벗어 나지않고
익지 않은 토마토이며 방문 한적 없는 곳이면 다음 토마토가 익는 날짜를 현재 날짜 +1을 한고 상태를 익음으로 변경
익은 토마토를 큐에 삽입한다. 그후 bfs가 끝났을때 안익은 토마토가 남아있는지 비교 한뒤 모두 익지 않다면 -1을 출력 하고 종료 하고 저장 된 날짜 중 가장 큰 값을 정답으로 갱신 한뒤 그것을 출력 한다.