백준
[C++] 백준 7569번 토마토
MINU.SHINNNN
2023. 1. 28. 17:50
https://www.acmicpc.net/problem/7569
7569번: 토마토
첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,
www.acmicpc.net
풀이
1. 맵 변수를 받을 때 -1과 1을 카운팅 해서 이미 익어있는 경우를 판별한다.
2. BFS로 방문한 곳은 1로 바꿔주고 ans = max(ans, dist+1)로 갱신한다. 이렇게 하면 모든 토마토가 익는데 걸리는 최소 일 수를 구할 수 있다.
3. 토마토가 1개 익을 때마다 cnt++ 해주고, BFS가 끝난 후 모두 익었는지 확인(1과 -1만 존재) 하면 된다.
#include <iostream>
#include <queue>
using namespace std;
int M, N, H;
int map[101][101][101];
int dr[6]={1, 0, -1, 0, 0, 0};
int dc[6]={0, 1, 0, -1, 0, 0};
int dh[6]={0, 0, 0, 0, 1, -1};
struct Info{
int r, c, h, dist;
Info(int a, int b, int height, int d){
r=a;
c=b;
h=height;
dist=d;
}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
// freopen("input.txt", "r", stdin);
cin >> M >> N >> H;
queue<Info> q;
int cnt=0, m_cnt=0;
for (int h=1; h<=H; h++){
for (int i=1; i<=N; i++){
for (int j=1; j<=M; j++){
cin >> map[i][j][h];
if (map[i][j][h]==1) {
q.push(Info(i,j,h,0));
cnt++;
}
if (map[i][j][h]==-1) m_cnt++;
}
}
}
if (cnt == M*N*H-m_cnt){
cout << 0 << endl;
return 0;
}
int ans=0;
while (!q.empty()){
Info v = q.front();
q.pop();
for (int i=0; i<6; i++){
int nr = v.r + dr[i];
int nc = v.c + dc[i];
int nh = v.h + dh[i];
if (nr<1 || nr>N || nc<1 || nc>M || nh<1 || nh>H) continue;
if (map[nr][nc][nh]==0){
map[nr][nc][nh]=1;
ans = max(ans, v.dist+1);
cnt++;
q.push(Info(nr, nc, nh, v.dist+1));
}
}
}
if (cnt != M*N*H-m_cnt) cout << -1 << endl;
else cout << ans << endl;
return 0;
}