본문으로 바로가기

[BFS] 7569번 토마토

category Algorithm/BOJ 문제풀이 2018. 12. 14. 19:35
7569_토마토

7569번 토마토

 

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


 

문제

철수의 토마토 농장에서는 토마토를 보관하는 큰 창고를 가지고 있다. 토마토는 아래의 그림과 같이 격자모양 상자의 칸에 하나씩 넣은 다음, 상자들을 수직으로 쌓아 올려서 창고에 보관한다.

img

창고에 보관되는 토마토들 중에는 잘 익은 것도 있지만, 아직 익지 않은 토마토들도 있을 수 있다. 보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다. 하나의 토마토에 인접한 곳은 위, 아래, 왼쪽, 오른쪽, 앞, 뒤 여섯 방향에 있는 토마토를 의미한다. 대각선 방향에 있는 토마토들에게는 영향을 주지 못하며, 토마토가 혼자 저절로 익는 경우는 없다고 가정한다. 철수는 창고에 보관된 토마토들이 며칠이 지나면 다 익게 되는지 그 최소 일수를 알고 싶어 한다.

토마토를 창고에 보관하는 격자모양의 상자들의 크기와 익은 토마토들과 익지 않은 토마토들의 정보가 주어졌을 때, 며칠이 지나면 토마토들이 모두 익는지, 그 최소 일수를 구하는 프로그램을 작성하라. 단, 상자의 일부 칸에는 토마토가 들어있지 않을 수도 있다.

 

입력

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H 가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100, 1 ≤ H ≤ 100 이다. 둘째 줄부터는 가장 밑의 상자부터 가장 위의 상자까지에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 하나의 상자에 담긴 토마토의 정보가 주어진다. 각 줄에는 상자 가로줄에 들어있는 토마토들의 상태가 M개의 정수로 주어진다. 정수 1은 익은 토마토, 정수 0 은 익지 않은 토마토, 정수 -1은 토마토가 들어있지 않은 칸을 나타낸다. 이러한 N개의 줄이 H 번 반복하여 주어진다.

 

출력

여러분은 토마토가 모두 익을 때까지 최소 며칠이 걸리는지를 계산해서 출력해야 한다. 만약, 저장될 때부터 모든 토마토가 익어있는 상태이면 0을 출력해야 하고, 토마토가 모두 익지는 못하는 상황이면 -1 을 출력해야 한다.

 

예제 입력

5 3 1
0 -1 0 0 0
-1 -1 0 1 1
0 0 0 1 1
5 3 2
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
4 3 2
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
-1 -1 -1 -1
1 1 1 -1

 

예제 출력

-1
4
0

 

해결방법

모든 토마토가 익을 때 까지, BFS 탐색을 수행하는 문제이다

 

⭐️ 솔루션 ⭐️**

BFS 탐색을 하며 dist 배열 값 넣어줌 (dist 배열은 토마토가 익기 위한 시간)

 

  • 처음에 사용자의 입력을 받을 때, 초기 익은 토마토를 벡터에 넣어준다
  • 초기 익은 토마토를 Queue 에 넣어주고 BFS 탐색을 수행한다
  • 6 방향을 탐색하며 익지 않은 토마토이고 아직 방문하지 않았다면 현재 위치에서 dist + 1 을 한 뒤, 큐에 넣어준다
  • 초기 익지 않은 토마토 중에 BFS 탐색에 영향을 받지 않은 곳이 있다면 -1 을 출력하고 전부 영향을 받았다면 dist 값 중 최대값을 출력해준다

 

 

소스코드

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <bitset>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define MAX 101
#define INF 987654321
using namespace std;

struct node {
    int x,y,z;
    
    node(int _x,int _y,int _z) : x(_x),y(_y),z(_z) {}
};

int n,m,h,ans;

int map[MAX][MAX][MAX];
int dist[MAX][MAX][MAX];
bool visited[MAX][MAX][MAX];

int dx[6] = {0,1,0,-1,0,0};
int dy[6] = {1,0,-1,0,0,0};
int dz[6] = {0,0,0,0,1,-1};

vector<node> ripe;

bool is_all_ripe(){
    for(int k=0; k<h; k++){
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                // 초기 안익은 토마토 중 BFS 탐색에서 방문하지 않은 노드가 있다면
                if(map[k][i][j]==0 && !visited[k][i][j]) return false;
            }
        }
    }
    return true;
}

void bfs(){
    queue<node> q;
    for(int i=0; i<ripe.size(); i++){
        int x = ripe[i].x;
        int y = ripe[i].y;
        int z = ripe[i].z;
        q.push(ripe[i]);
        dist[x][y][z] = 0;
        visited[x][y][z] = true;
    }
    
    while(!q.empty()){
        int x = q.front().x;    // Height
        int y = q.front().y;    // Row
        int z = q.front().z;    // Col
        q.pop();
        
        for(int i=0; i<6; i++){
            int nx = x + dx[i];
            int ny = y + dy[i];
            int nz = z + dz[i];
            
            if(nx<0 || nx>=h || ny<0 || ny>=m || nz<0 || nz>=n) continue;
            
            if(map[nx][ny][nz]==0 && !visited[nx][ny][nz]){
                q.push(node(nx,ny,nz));
                dist[nx][ny][nz] = dist[x][y][z] + 1;
                visited[nx][ny][nz] = true;
                ans = max(ans,dist[nx][ny][nz]);
            }
        }
    }
    
    if(is_all_ripe())
        cout << ans << "\n";
    else
        cout << -1 << "\n";
    
}

int main(int argc, const char * argv[]) {
    // cin,cout 속도향상
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    
    cin >> n >> m >> h;
    
    for(int k=0; k<h; k++){
        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                cin >> map[k][i][j];
                
                if(map[k][i][j] == 1) ripe.push_back(node(k,i,j));
            }
        }
    }
    
    ans = 0;
    memset(visited, false, sizeof(visited));
    
    bfs();
}

'Algorithm > BOJ 문제풀이' 카테고리의 다른 글

[BFS] 2146번 다리 만들기  (0) 2018.12.16
[BFS] 3055번 탈출  (0) 2018.12.14
[BFS] 5014번 스타트링크  (0) 2018.12.14
[BFS] 11724번 연결 요소의 개수  (0) 2018.12.14
[BFS] 2589번 보물섬  (0) 2018.12.14