📜 코딩테스트/BAEKJOON\BFS, DFS

백준 7576번 : 토마토 (JAVA) 문제 풀이

2021. 6. 24. 15:31
목차
  1. ✏️ 문제
  2. 🔐 문제 해결
  3. 🖥 전체 코드
반응형

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

 

7576번: 토마토

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

www.acmicpc.net


 

✏️ 문제

 

🔐 문제 해결

이 문제는 미로 탐색 문제처럼 풀면 된다. 

대신 이 문제에서 주의해야할 점은 미로 탐색 문제처럼 한곳에서 출발하는게 아니라, 시작점이 여러지점이라는 점이다.

이것 때문에 머리 아팠는데 생각해보면 그리 어렵지 않다.

아래 코드를 보면서 살펴보자.

int[][] days = new int[N][M];
int[][] tomatos = new int[N][M];

// N, M 주의! 우리는 M을 행, N을 열로 사용!
for(int i=0; i<M; i++){
	st = new StringTokenizer(bf.readLine();
	for(int j=0; j<N; j++){
	    int num = Integer.parseInt(st.nextToken());
          tomatos[i][j] = num;
          // 1(익은 토마토)이면 큐에 넣어준다!
          if( num == 1 ){
              qu.offer(new Pair(i, j));
              days[i][j] = 0;
          }else{
              days[i][j] = -1;
          }
    }
}

 

먼저 익은 토마토(1)일때는 큐에 넣어준다! (시작점 세팅).

그리고, 익지 않았으면 days[i][j]에 -1값을 넣어준다. -> 나중에 방문여부를 확인하기 위해서

 

가장 핵심이 되는 코드이다! 

익은 토마토 상,하,좌,우에 익지 않은 토마토가 있다면 토마토를 익은 상태로 바꾸고, 해당 days의 값을 +1해서 넣어준다!!

아래 코드를 살펴보자.

while(!qu.isEmpty()){
    Pair p = qu.poll();
    
    // 상하좌우 순회
    for(int i=0; i<4; i++){
        int nX = p.x + dx[i];
        int nY = p.y + dy[i];
        
        if(nX <0 || nX >= N || nY < 0 || nY >= M){
            continue;
        }
        // 토마토가 없거나, 이미 방문했으면 PASS!
        if(tomatos[nX][nY] == -1 || days[nX][nY] != -1){
            continue;
        }
        // 익은 토마토를 큐에 넣어주고, 안익은 토마토의 개수 -1
        qu.offer(new Pair(nX, nY)); notYet--;
        // 날짜를 +1 하여 넣어줍니다.
        days[nX][nY] = days[p.x][p.y] + 1;
        // 해당 날짜가 최종 날짜인지 구분
        if(result < days[nX][nY]){
            result = days[nX][nY];
        }
    }
}

미리 넣어줬던 익은 토마토를 큐에서 차례대로 꺼내면서, 해당 토마토의 상,하,좌,우를 탐색해서 안익은 토마토가 있다면 큐에 넣어주고, 해당 토마토의 날짜를 자신을 익히게 했던 토마토(?)의 날짜 + 1 한 값을 넣어준다! (말이 이상한데 잘 이해해보자..)

 

🖥 전체 코드

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

public class Main {
    public static void main(String args[]) throws IOException {
      BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
      StringTokenizer st = new StringTokenizer(bf.readLine());
      
      int result = 0;      // 최종 날짜
      int notYet = 0;      // 안익은 토마토
      int M = Integer.parseInt(st.nextToken());
      int N = Integer.parseInt(st.nextToken());
      int[][] days = new int[N][M];     // 날짜를 저장할 2차원배열
      int[][] tomatos = new int[N][M];  // 토마토의 상태를 저장할 2차원배열
      
      Queue<Pair> qu = new LinkedList<>();
      int[] dx = {1, 0 , -1, 0};    // 상하좌우 좌표 계산을 위한 배열
      int[] dy = {0, 1, 0, -1};
      
      
      // 토마토 상태 입력
      for(int i=0; i<N; i++){
          st = new StringTokenizer(bf.readLine());
          for(int j=0; j<M; j++){
              days[i][j] = -1;  // 방문여부를 위해 -1로 초기화
              int num = Integer.parseInt(st.nextToken());
              tomatos[i][j] = num;
              if(num == 1){
                  qu.offer(new Pair(i, j)); // 익은 토마토만 큐에 넣어준다.
                  days[i][j] = 0;           // 해당 날짜 0일으로 세팅
              }else if(num == 0){
                  notYet++;     // 익지 않은 토마토 +1
              }
          }
      }
      
      // 안익은 토마토가 없다면 종료.
      if(notYet == 0){
          System.out.print(0);
          System.exit(0);
      }
      
      // 익은 토마토가 만약 n개 일때, 걸린 날짜 / n 인가?
      while(!qu.isEmpty()){
          Pair p = qu.poll();
          
          // 상하좌우 순회
          for(int i=0; i<4; i++){
              int nX = p.x + dx[i];
              int nY = p.y + dy[i];
              
              if(nX <0 || nX >= N || nY < 0 || nY >= M){
                  continue;
              }
              // 토마토가 없거나, 이미 방문했으면 PASS!
              if(tomatos[nX][nY] == -1 || days[nX][nY] != -1){
                  continue;
              }
              // 익은 토마토를 큐에 넣어주고, 안익은 토마토의 개수 -1
              qu.offer(new Pair(nX, nY)); notYet--;
              // 날짜를 +1 하여 넣어줍니다.
              days[nX][nY] = days[p.x][p.y] + 1;
              // 해당 날짜가 최종 날짜인지 구분
              if(result < days[nX][nY]){
                  result = days[nX][nY];
              }
          }
      }
      
      // 만약 아직도 익지 않은 토마토가 있다면 -1 출력!
      if(notYet > 0){
          System.out.print(-1);
      }else{
          System.out.print(result);
      }
    }
    
    public static class Pair{
        int x, y;
        
        public Pair(int x, int y){
            this.x = x;
            this.y = y;
        }
        
        public int getX(){
            return x;
        }
        public int getY(){
            return y;
        }
        public void setX(int x){
            this.x = x;
        }
        public void setY(int y){
            this.y = y;
        }
    }
}

 

반응형
저작자표시 (새창열림)
  1. ✏️ 문제
  2. 🔐 문제 해결
  3. 🖥 전체 코드
'📜 코딩테스트/BAEKJOON\BFS, DFS' 카테고리의 다른 글
  • 백준 2206번 : 벽 부수고 이동하기 (JAVA) 문제 풀이
  • 백준 7569번 : 토마토 (JAVA) 문제 풀이
  • 백준 2178번 : 미로 탐색 (JAVA) 문제 풀이
  • 백준 1926번 : 그림 (JAVA) 문제 풀이
iseunghan
iseunghan
꾸준하게 열심히..
iseunghan
iseunghan

공지사항

  • 어제보다 나은 오늘이 되기 위해 🔥
  • 분류 전체보기 (262)
    • 💐 Spring (14)
      • 개념 및 이해 (2)
      • Spring 핵심 기술 (24)
      • Spring REST API (8)
      • Spring MVC, DB 접근 기술 (7)
      • Spring Security (23)
      • Spring in Action (1)
    • 🌻 JAVA (84)
      • 자바 ORM 표준 JPA 프로그래밍 (20)
      • 알고리즘, 자료구조 (13)
      • 디자인 패턴 (7)
      • 정리정리정리 (43)
      • JUnit (1)
    • 🔖 Snippets (3)
      • Javascript (3)
    • ⚙️ Devops (22)
      • ⛏ Git (11)
      • 🐳 Docker (6)
      • 🐧 Linux (3)
      • 🌈 Jenkins (1)
      • 📬 Kafka (1)
    • 💬 ETC.. (4)
      • 💻 macOS (2)
    • 🌧️ ORM (2)
      • JPA (2)
    • 🐍 Python (3)
    • 📚 Databases (15)
      • 오라클로 배우는 데이터베이스 개론과 실습(2판) (3)
      • RealMySQL 8.0 (8)
    • 🔥 Computer Science (5)
      • 📡 네트워크 (5)
    • 🏷️ 협업 (1)
    • 📜 코딩테스트 (38)
      • BAEKJOON\수학 1, 수학 2 (8)
      • BAEKJOON\재귀 (5)
      • BAEKJOON\브루트 포스 (3)
      • BAEKJOON\정렬 (1)
      • BAEKJOON\백트래킹 (5)
      • BAEKJOON\BFS, DFS (6)
      • BAEKJOON\이분탐색 (1)
      • BAEKJOON\다이나믹 프로그래밍 (9)
      • BAEKJOON\그리디 알고리즘 (0)
    • ✨ ISEUNGHAN (1)

인기 글

전체
오늘
어제
반응형
hELLO · Designed By 정상우.
iseunghan
백준 7576번 : 토마토 (JAVA) 문제 풀이
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

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

블로그 게시글

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

모든 영역

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

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