알고리즘/DFS & BFS

[백준]JAVA - 7576번: 토마토

K.두부 2022. 10. 7. 01:35
반응형

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

 

7576번: 토마토

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

www.acmicpc.net

풀이

최근에 풀었던 미로탐색(2178번), 숨바꼭질(1697번) 문제와 동일한 유형이다.

이 문제를 풀어보기 전에 먼저 풀어보는 걸 추천한다.

 

위 문제를 풀었으면 bfs 방법에 대해서는 확실히 이해했다고 가정하고 간단하게 설명하겠다.

이번 문제는 익은 토마토를 기준으로 상하좌우 한 칸씩 모든 토마토를 익혀야하는 문제이다. 즉, bfs를 중간에 끊지말고 끝까지 돌려야한다는 의미이다.

 

2차원 배열이기 때문에 Node 라는 이름의 클래스를 생성해서 노드 형태로 Queue를 만들어준다.

이후에 토마토 배열에서 익은 토마토(1)을 찾아서 x, y 값을 Queue에 넣어준다.

Queue에 들어간 x, y 값을 기준으로 상하좌우를 보면서 토마토가 들어있지 않은 칸(-1)을 제외한 안익은 토마토(0)을 찾아서 +1씩 해주면서 Queue에 넣고 빼고를 반복해주면 된다.

 

예외로는 토마토가 들어있지 않은 칸(-1)가 상하좌우를 가로막고 있어서 더 이상 나아갈 수 없을 경우이다.

이건 그냥 bfs를 모두 돌린 후에 2중 for문으로 토마토 배열을 돌면서 0인 값이 있으면 -1을 반환해주면 된다.

 

<최종코드>

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
		
        class Node {
            int x;
            int y;
			
            public Node (int x, int y) {
                this.x = x;
                this.y = y;
            }
        }
		
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
		
        int[] cx = {-1, 0, 1, 0};
        int[] cy = {0, -1, 0, 1};
        int M = Integer.parseInt(st.nextToken());
        int N = Integer.parseInt(st.nextToken());
		
        int[][] map = new int[M][N];
        Queue<Node> q = new LinkedList<>();
		
        for (int i=0; i<N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j=0; j<M; j++) {
                map[j][i] = Integer.parseInt(st.nextToken());
				
                if (map[j][i] == 1) {
                    q.add(new Node(j, i));
                }
            }
        }

        while (!q.isEmpty()) {
            Node now = q.poll();
			
            for (int i=0; i<4; i++) {
                int row = now.x + cx[i];
                int col = now.y + cy[i];
				
                if (row >= 0 && row < M && col >= 0 && col < N && map[row][col] == 0) {
                    map[row][col] = map[now.x][now.y] + 1;
                    q.add(new Node(row, col));
                }
            }
        }
		
        int max = -1;
        for (int i=0; i<N; i++) {
            for (int j=0; j<M; j++) {
                max = Math.max(max, map[j][i]);
				
                // 모든 토마토를 익히지 못 한 경우
                if (map[j][i] == 0) {
                    System.out.println(-1);
                    return;
                }
            }
        }
		
        System.out.println(max-1);
    }
}

 

반응형