자료구조와 알고리듬 With Java/[Study] BAEKJOON 프로그래머스 CodeUp LeetCode

Backjoon 7576 BFS 토마토

계란💕 2022. 5. 3. 23:56

  Ex) 며칠 후에 상자 안의 토마토가 모두 익는지 구하라.

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

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

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

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 상자에 담긴 토마토의 정보가 주어진다. 하나의 줄에는 상자 가로줄에 들어있는 토마토의 상태가 M개의 정수로 주어진다. 정수 1은 익은 토마토, 정수 0은 익지 않은 토마토, 정수 -1은 토마토가 들어있지 않은 칸을 나타낸다.

토마토가 하나 이상 있는 경우만 입력으로 주어진다.

 

 

  Sol)

  - main함수에 인접행렬 값을 입력 받으면서 가장 처음에 스캔한 인접행렬의 값이 1일 때만 각각의 queue에 offer한다.

    -> for문을 모두 돌리고나서 BFS메서드를 실행한다.

 

  - 방문행렬과 인접행렬의 값이 둘 다 0인 i, j가 있으면 빈 공간(인접행렬 = -1)때문에 방문하지 못하여 익지 않은 경우이다.

    -> 따라서, 이 때 토마토가 모두 익지 못하는 경우이므로 -1출력하고 return한다.

 

  - 최단거리를 이용하는 유형과 마찬가지로 BFS 알고리즘을 이용한다.

    -> 최단 거리를 이용하기 때문에 거리에 대한 부분도 같이 Queue에 더하고 poll()해주면 편리하다.

    -> DFS는 재귀함수로 이용하는 것과 다르게 BFS는 while(!q.isEmpty()) 를 이용해서 반복시킨다.

 

  - 마지막에 answer에서 1뺀 값을 리턴한다.

    -> while문의 가장 마지막 반복문에서  두 번째 if문을 실행하기전에  첫 번째 if문에서 break된다.

    -> 그런데, break되기 전에  다음 방문을 하지 않고 종료될 예정임에도 nextDis에 1을 더해줬기 때문에 최종적으로는 answer - 1을 해줘야 정답이 된다.  

 

<hide/>
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Tomato {

	static int MAX_COUNT = 2001;
	static int [][] AdjMatrix = new int[MAX_COUNT][MAX_COUNT];
	static int [][] VisitMatrix = new int[MAX_COUNT][MAX_COUNT];
	static int Width; 
	static int Height;
	static int DIRECTION = 4;
	static int [][] DirMatrix = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
	static Queue<Integer> queueRow = new LinkedList<>();
	static Queue<Integer> queueCol = new LinkedList<>();
	static Queue<Integer> queueDis = new LinkedList<>();
	static int Distance = 0;
	static int answer = 0;
	
	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		Width = scan.nextInt();
		Height = scan.nextInt();
		for(int i = 1; i <= Height; ++i) {
			for(int j = 1; j<= Width; ++j) {
				AdjMatrix[i][j] = scan.nextInt();
				if(1 == AdjMatrix[i][j] ) {
					queueRow.offer(i);
					queueCol.offer(j);
					queueDis.offer(1);
				}
			}
		}
		BFS();
		   for (int i = 1; i <= Height; ++i)
		    {
		        for (int j = 1; j <= Width; ++j)
		        {
		            if (0 == VisitMatrix[i][j] && 0 == AdjMatrix[i][j])
		            {
		                System.out.printf("-1");
		                return;
		            }
		        }
		    }
		
		System.out.print(answer - 1);
	}
		
	public static void BFS() {
		while(false == queueRow.isEmpty() ) {
			int currRow = queueRow.poll();
			int currCol = queueCol.poll();
			int currDis = queueDis.poll();
			for(int i = 0;i < DIRECTION; ++i) {
				int nextRow = currRow + DirMatrix[i][0];
				int nextCol = currCol + DirMatrix[i][1];
				int nextDis = currDis + 1;
				if(1 == VisitMatrix[nextRow][nextCol]) continue;
				if(0 == AdjMatrix[nextRow][nextCol] &&
					1 <= nextRow && nextRow <= Height &&
					1 <= nextCol && nextCol <= Width) {
					answer = nextDis;
					VisitMatrix[nextRow][nextCol] = 1;
					queueRow.offer(nextRow);
					queueCol.offer(nextCol);
					queueDis.offer(nextDis);
					AdjMatrix[nextRow][nextCol] = 1;
					System.out.printf("[%d] (%d, %d)->(%d, %d)\n", nextDis, currRow, currCol, nextRow, nextCol);
					
					for(int k = 1; k <= Height; ++k) {
						for(int j = 1; j<= Width; ++j) {
							System.out.printf(AdjMatrix[k][j] + " ");
						}
						System.out.println();
					}
				}
			}
		}
	}
}

 

 

  Note) 입출력 예시

<hide/>

[입력]
6 4
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 1

[출력]
8


[입력]
11 11
0 0 0 0 1 0 -1 -1 0 0 0 
0 -1 1 1 0 0 1 1 0 0 0 
0 0 0 0 -1 1 0 0 1 0 0 
0 0 -1 0 0 -1 -1 0 0 0 -1 
1 1 -1 0 0 1 0 0 0 -1 1 
-1 0 0 0 0 0 1 0 0 1 0 
0 1 0 -1 0 0 0 0 1 1 1 
0 0 0 1 0 0 0 0 0 -1 0 
0 0 0 0 0 0 0 0 0 0 -1 
-1 0 0 0 0 0 1 1 0 0 1 
-1 0 0 0 0 -1 -1 0 0 0 -1

[출력]
4


[입력]
5 3
0 -1 0 0 0 
-1 -1 0 1 1
0 0 0 1 1

[출력]
-1


[입력]
2 2
1 -1
-1 1

[출력]
0

 

 

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