[백준/Java] 7569 - 토마토

2025. 9. 15. 14:22·코딩테스트/백준

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

문제


풀이

3중 배열에서 BFS를 활용하는 문제이다

익은 토마토는 하루가 지나면 상하좌우앞뒤의 익지 않은 토마토를 익게한다

이전까지는 네 방향을 확인했는데 3중 배열이니 여섯 방향을 확인해야 한다

 

익은 토마토는 첫날부터 동시에 주변 토마토를 익게한다

따라서 BFS를 시작하기 전에, 처음에 익어있던 모든 토마토의 위치를 큐에 넣고 시작해야 한다

 

토마토가 며칠째에 익었는지 기록하기 위해 따로 3차원 배열을 만들고 -1 로 초기화 해두면 방문 여부와 날짜 계산을 동시에 할 수 있다

 

자세한 것은 코드를 보자

코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

	static int N, M, H;
	static int[][][] arr;
	static int[][][] days;

	static int[] dx = {-1, 1, 0, 0, 0, 0}; // 상하
	static int[] dy = {0, 0, -1, 1, 0, 0}; // 좌우
	static int[] dh = {0, 0, 0, 0, -1, 1}; // 앞뒤

	static Queue<int[]> queue = new LinkedList<>();

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		StringBuilder sb = new StringBuilder();

		st = new StringTokenizer(br.readLine());
		M = Integer.parseInt(st.nextToken()); // 가로
		N = Integer.parseInt(st.nextToken()); // 세로
		H = Integer.parseInt(st.nextToken()); // 높이
		arr = new int[H][N][M]; // 토마토 배열
		days = new int[H][N][M]; // 최대 며칠이 걸렸는지 확인하는 배열

		// days 배열을 -1로 초기화하면 방문 여부도 같이 확인할 수 있다
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < N; j++) {
				for (int k = 0; k < M; k++) {
					days[i][j][k] = -1;
				}
			}
		}

		// 토마토 배열 입력
		boolean state = false;
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < N; j++) {
				st = new StringTokenizer(br.readLine());
				for (int k = 0; k < M; k++) {
					arr[i][j][k] = Integer.parseInt(st.nextToken());
					// 입력이 1이면
					if (arr[i][j][k] == 1) {
						// 큐에 좌표를 넣어준다
						queue.add(new int[]{i, j, k});
						// days 배열 값을 0으로 한다 (방문 처리)
						days[i][j][k] = 0;
					} else if (arr[i][j][k] == 0) {
						state = true; // 익지 않은 과일이 있으면 state를 true
					}
				}
			}
		}

		// state가 true일 때만 bfs를 호출한다
		if(state) bfs();

		// bfs 탐색 후 토마토가 모두 익었는지 확인하는 변수
		boolean check = true;
		for (int[][] ints : arr) {
			for (int[] anInt : ints) {
				for (int i : anInt) {
					// 0이 하나라도 남아있으면
					if (i == 0) {
						check = false; // check 변수를 false로
					}
				}
			}
		}
		// 다 익었다면
		if (check) {
			// days 배열에서 최댓값을 찾아 출력한다
			int max = 0;
			for (int[][] day : days) {
				for (int[] ints : day) {
					for (int i : ints) {
						max = Math.max(max, i);
					}
				}
			}
			System.out.println(max);
		} else {
			// 익지 않았다면 -1을 출력
			System.out.println(-1);
		}
		br.close();
	}

	static void bfs() {
		// 큐가 빌 때까지
		while(!queue.isEmpty()) {
			// 큐에서 좌표 하나를 뺀다
			int[] coord = queue.poll();
			int h = coord[0];
			int x = coord[1];
			int y = coord[2];
			for (int i = 0; i < 6; i++) {
				// 상하좌우앞뒤 탐색
				int nx = x + dx[i];
				int ny = y + dy[i];
				int nh = h + dh[i];

				// 해당 죄표가 배열 범위 안에 있고
				if (nx >= 0 && nx < N && ny >= 0 && ny < M && nh >= 0 && nh < H) {
					// 방문하지 않았고 익지 않은 토마토라면
					if (days[nh][nx][ny] == -1 && arr[nh][nx][ny] == 0) {
						queue.add(new int[]{nh, nx, ny}); // 큐에 넣어줌
						days[nh][nx][ny] = days[h][x][y] + 1; // days 배열에 며칠이 지났는지 기록
						arr[nh][nx][ny] = 1; // 익음 상태로 바꿔준다
					}
				}
			}
		}
	}
}

결과

'코딩테스트/백준' 카테고리의 다른 글
  • [백준/Java] 16928 - 뱀과 사다리 게임
  • [백준/Java] 10026 - 적록색약
  • [백준/Java] 5430 - AC
  • [백준/Java] 1074 - Z
KDH.dev
KDH.dev
  • KDH.dev
    CodingHard
    KDH.dev
  • 전체
    오늘
    어제
    • 전체글 (82)
      • 코딩테스트 (74)
        • 프로그래머스 (13)
        • 백준 (61)
      • CS (4)
        • 네트워크 (4)
      • Spring (1)
      • Java (3)
        • 자료구조 (3)
        • 알고리즘 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    30804
    5525
    프로그래머스
    프로그래머스 Lv.0
    코딩테스트
    13913
    16935
    멀티캠퍼스it부트캠프
    [LG유플러스] 유레카 백엔드 개발자
    CS
    부트캠프후기
    백준
    자바
    11660
    14940
    네트워크
    18111
    21736
    17626
    자료구조
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
KDH.dev
[백준/Java] 7569 - 토마토
상단으로

티스토리툴바