문제 설명
현수는 토마토를 보관하는 창고에서 익은 토마토가 익지 않은 토마토에 영향을 줘서 며칠 뒤 모든 토마토가 익는지를 알고 싶어한다.
격자 형태의 창고에서 하루마다 익은 토마토가 인접한 칸의 익지 않은 토마토를 익게 한다.
창고는 N행 M열로 구성되어 있으며 각 칸은 다음 중 하나이다:
- 1: 익은 토마토
- 0: 익지 않은 토마토
- -1: 토마토가 없는 칸
모든 토마토가 익기까지의 최소 일수를 구하라.
모든 토마토가 처음부터 익어 있으면 0,
절대 익지 못하는 토마토가 존재하면 -1을 출력한다.
입력 & 출력
입력
- 첫 줄에 M(가로), N(세로) (2 ≤ M, N ≤ 1,000)
- 다음 N줄에 M개의 정수 (토마토 상태)
출력
- 최소 일수 (불가능한 경우는 -1)
예시
입력:
6 4
0 0 -1 0 0 0
0 0 1 0 -1 0
0 0 -1 0 0 0
0 0 0 0 -1 1
출력:
4
해결 방법
- 이 문제는 여러 개의 익은 토마토(1) 에서 동시에 BFS 탐색을 시작해야 하므로 Multi-Source BFS 로 해결한다.
- 큐에 익은 토마토의 좌표를 모두 먼저 넣고, BFS를 돌리면 날짜(dis)를 1일씩 늘려가며 확산시킬 수 있다.
- 모든 토마토가 익는 데 걸린 최대 날짜(dis[x][y]) 를 정답으로 출력한다.
- BFS 이후에도 0이 남아 있다면 익지 못한 토마토가 있으므로 -1을 출력한다.
코드 구현
package partDfsBfs;
import java.util.*;
class Point {
public int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Problem12 {
static int[] dx = {-1, 0, 1, 0}; // 상우하좌
static int[] dy = {0, 1, 0, -1};
static int n, m;
static int[][] board, dis;
static Queue<Point> Q = new LinkedList<>();
public void BFS() {
while (!Q.isEmpty()) {
Point tmp = Q.poll();
for (int i = 0; i < 4; i++) {
int nx = tmp.x + dx[i];
int ny = tmp.y + dy[i];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && board[nx][ny] == 0) {
board[nx][ny] = 1;
Q.offer(new Point(nx, ny));
dis[nx][ny] = dis[tmp.x][tmp.y] + 1;
}
}
}
}
public static void main(String[] args) {
Problem12 T = new Problem12();
Scanner kb = new Scanner(System.in);
m = kb.nextInt();
n = kb.nextInt();
board = new int[n][m];
dis = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
board[i][j] = kb.nextInt();
if (board[i][j] == 1) Q.offer(new Point(i, j)); // 초기 익은 토마토들
}
}
T.BFS();
boolean flag = true;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (board[i][j] == 0) flag = false;
}
}
int answer = Integer.MIN_VALUE;
if (flag) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
answer = Math.max(answer, dis[i][j]);
}
}
System.out.println(answer);
} else {
System.out.println(-1);
}
kb.close();
}
}
코드 설명
- Point 클래스: 현재 좌표 저장
- Q: 익은 토마토들의 위치를 큐에 저장하여 동시에 BFS 수행
- dis[x][y]: (x,y) 위치가 익는 데 걸린 일수 저장
- board[x][y] = 1: 익었음을 표시하고 다시 방문하지 않게 함
시간 복잡도
- 격자 크기: N x M
- BFS는 각 칸을 최대 1번 방문
- 시간복잡도: O(N × M)
→ 입력 최대 크기 1,000 × 1,000 = 1,000,000 → 충분히 처리 가능
출처: 인프런 자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
https://www.inflearn.com/course/자바-알고리즘-문제풀이-코테대비/dashboard
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비 강의 | 김태원 - 인프런
김태원 | , 자바(Java) 알고리즘 문제풀이 채점사이트를 통해 기초부터 준비해보세요! 💪 [사진] 이 강의는 [사진] 자바(Java)로 코딩테스트 준비를 하고 계신 분께 추천드려요! 문제는 기초~ 중급
www.inflearn.com
'코딩테스트 > 자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비' 카테고리의 다른 글
| 섹션 8 DFS, BFS - 13. 섬나라 아일랜드(BFS) (1) | 2025.06.09 |
|---|---|
| 섹션 8 DFS, BFS - 13. 섬나라 아일랜드 (0) | 2025.06.09 |
| 섹션 8 DFS, BFS - 11. 미로의 최단거리 통로(BFS) (0) | 2025.05.26 |
| 섹션 8 DFS, BFS - 10. 미로탐색(DFS) (1) | 2025.05.26 |
| 섹션 8. DFS, BFS 활용 - 9. 조합 구하기 (1) | 2025.05.23 |