알고리즘

[BOJ] 토마토 - 7576

2023. 6. 16. 12:35
목차
  1. 🎨 문제
  2. 📘 풀이
  3. 📗 코드

🎨 문제

 

7576번: 토마토

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

www.acmicpc.net

📘 풀이

이 문제는 BFS로 풀 수 있습니다. 익은 토마토를 큐에 넣고 빼면서 주변 토마토를 익은 토마토로 만들어주면 됩니다. 

 

전체 토마토의 개수를 셉니다. 토마토 농장에는 벽이 있습니다. 입력을 받을 때 벽에는 토마토가 없기 때문에 전체 토마토 개수에서 벽 부분은 빼줍니다. 그리고 익은 토마토일 경우 큐에 토마토를 담아 둡니다.

for (int i = 0; i < N; i++) {
    StringTokenizer st = new StringTokenizer(br.readLine());
    for (int j = 0; j < M; j++) {
        MAP[i][j] = Integer.parseInt(st.nextToken());
        if (MAP[i][j] == 1) {
            TOMATOS.add(new int[]{i, j});
            VISITED[i][j] = true;
        }
        if (MAP[i][j] == -1) {
            WALL += 1;
        }
    }
}

현재 익은 토마토로 BFS를 하여 다음 번 익은 토마토를 큐에 넣어줍니다. 이 때 몇 번의 사이클이 도는지 계산해야 합니다. 저는 큐가 빌 때까지 도는 while문과 현재 큐에 들어있는 토마토의 개수만큼만 반복하는 for문으로 한 사이클을 돌았습니다.

 

만약 모든 토마토를 익힐 수 없다면 -1을 반환해야 하기 때문에 BFS가 종료되었을 때 익은 토마토의 개수와 BFS의 결과를 비교해 모든 토마토가 익었는지 확인합니다.

private static int bfs() {
    final int[] dR = {0, 0, 1, -1};
    final int[] dC = {1, -1, 0, 0};

    int result = 0;
    int rest = N * M - WALL - TOMATOS.size();
    while (!TOMATOS.isEmpty()) {
        int size = TOMATOS.size();

        for (int i = 0; i < size; i++) {
            int[] cur = TOMATOS.poll();
            int cR = cur[0];
            int cC = cur[1];
            for (int j = 0; j < 4; j++) {
                int nR = cR + dR[j];
                int nC = cC + dC[j];
                if (nR < 0 || nC < 0 || nR >= N || nC >= M) continue;
                if (VISITED[nR][nC]) continue;
                if (MAP[nR][nC] == -1) continue;

                VISITED[nR][nC] = true;
                TOMATOS.add(new int[]{nR, nC});
                rest -= 1;
            }
        }

        result += 1;
    }

    if (rest == 0) return result - 1;

    return -1;
}

📗 코드

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

import static java.lang.System.in;

public class Main {

    static int N, M, WALL;
    static int[][] MAP;
    static Queue<int[]> TOMATOS;
    static boolean[][] VISITED;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        int[] input = Arrays.stream(br.readLine().split(" "))
                .mapToInt(Integer::parseInt)
                .toArray();
        N = input[1];
        M = input[0];
        WALL = 0;
        MAP = new int[N][M];
        TOMATOS = new LinkedList<>();
        VISITED = new boolean[N][M];

        for (int i = 0; i < N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                MAP[i][j] = Integer.parseInt(st.nextToken());
                if (MAP[i][j] == 1) {
                    TOMATOS.add(new int[]{i, j});
                    VISITED[i][j] = true;
                }
                if (MAP[i][j] == -1) {
                    WALL += 1;
                }
            }
        }
        int answer = bfs();
        System.out.println(answer);
    }

    private static int bfs() {
        final int[] dR = {0, 0, 1, -1};
        final int[] dC = {1, -1, 0, 0};

        int result = 0;
        int rest = N * M - WALL - TOMATOS.size();
        while (!TOMATOS.isEmpty()) {
            int size = TOMATOS.size();

            for (int i = 0; i < size; i++) {
                int[] cur = TOMATOS.poll();
                int cR = cur[0];
                int cC = cur[1];
                for (int j = 0; j < 4; j++) {
                    int nR = cR + dR[j];
                    int nC = cC + dC[j];
                    if (nR < 0 || nC < 0 || nR >= N || nC >= M) continue;
                    if (VISITED[nR][nC]) continue;
                    if (MAP[nR][nC] == -1) continue;

                    VISITED[nR][nC] = true;
                    TOMATOS.add(new int[]{nR, nC});
                    rest -= 1;
                }
            }

            result += 1;
        }

        if (rest == 0) return result - 1;

        return -1;
    }
}
저작자표시 (새창열림)

'알고리즘' 카테고리의 다른 글

[BOJ] LCS - 9251  (0) 2023.06.20
[BOJ] 토마토 - 7569  (0) 2023.06.19
[BOJ] 팰린드롬?  (0) 2023.06.09
[BOJ] 경로 찾기 - 1513  (0) 2023.06.08
[BOJ] 사탕 가게 - 4781  (0) 2023.06.05
  1. 🎨 문제
  2. 📘 풀이
  3. 📗 코드
'알고리즘' 카테고리의 다른 글
  • [BOJ] LCS - 9251
  • [BOJ] 토마토 - 7569
  • [BOJ] 팰린드롬?
  • [BOJ] 경로 찾기 - 1513
acisliver
acisliver
acisliver
와당탕탕 개발놀이터
acisliver
전체
오늘
어제
  • 분류 전체보기 (65)
    • 회고 (11)
    • Spring (3)
    • 알고리즘 (21)
    • Java (2)
    • DevOps (2)
    • Shell (2)
    • Nginx (1)
    • Database (22)
    • Project (1)

블로그 메뉴

  • 태그
  • 방명록
  • GitHub
  • Notion

공지사항

인기 글

태그

  • 인덱스
  • 프로그래머스
  • 풀 테이블 스캔
  • Bash
  • 풀스택
  • DevOps
  • 백준
  • 코딩테스트
  • Leetcode
  • FOSSLight
  • 우아한테크코스
  • 프리코스
  • 오픈소스
  • binarySearch
  • FuntionalInterface
  • Shell
  • 오픈소스 컨트리뷰톤
  • spring boot
  • mysql
  • 자바
  • dp
  • 알고리즘
  • Spring
  • 카카오
  • 이진탐색
  • 이분탐색
  • innodb
  • 풀 인덱스 스캔
  • 구름톤 트레이닝
  • Java

최근 댓글

최근 글

hELLO · Designed By 정상우.
acisliver
[BOJ] 토마토 - 7576
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.