본문 바로가기
알고리즘 algorithms

[백준 2638 Java] 치즈

by 괴로운데이빗 2020. 10. 27.

 

ㅇㅈㅇ

치즈 안쪽은 안녹는 줄 나중에 앎

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

class QueData {

    int i;
    int j;

    public QueData(int i, int j) {
        this.i = i;
        this.j = j;
    }
}

class Main
{
    static int N;
    static int M;
    static int[][] base_pan;
    static int[][] temp_pan;
    static boolean[][] visit_pan;

    static int[] move_1 = {-1,1,0,0};
    static int[] move_2 = {0,0,-1,1};
    static Queue que = new LinkedList();

    public static void main (String[] args) throws java.lang.Exception
    {

        Scanner sc = new Scanner(System.in);
        N = Integer.parseInt(sc.next());
        M = Integer.parseInt(sc.next());

        int finished_cnt = 0;	// 빈 칸의 개수를 셈

        base_pan = new int[N][M];
        for(int i=0;i<N;i++) {
            for(int j=0;j<M;j++) {
                base_pan[i][j]=Integer.parseInt(sc.next());
                if(base_pan[i][j]==0) {
                    finished_cnt++;
                }
            }
        }

        int hour = 0;
		// 치즈가 1칸이라도 있을 때만 while문을 돔
        while( finished_cnt!=(N*M) ) {
            finished_cnt = 0;	// 빈칸의 개수를 0으로 놓고 루프를 돌며 다시 빈칸의 개수를 셈
        	temp_pan = new int[N][M];	// 각 치즈가 노출된 공기칸을 센다.
            visit_pan =  new boolean[N][M];

            int org_i = 0;
            int org_j = 0;
            int temp_i=0;
            int temp_j=0;
            int molt_cnt;
            
            for(int i=0;i<N;i++) {
                for(int j=0;j<M;j++) {
            		
					// 행렬의 테두리, 0부터
					// 그에 인접한 0만을 que에 담아
					// 상하좌우에 위치한 치즈의 노출면을 센다.(치즈 안의 공간은 치즈가 녹지 않음)
					if( i>0&&i<(N-1)&&j>0&&j<(M-1) ) {
						continue;
					}
                    if(visit_pan[i][j]) {
                        continue;
                    }
                    if(base_pan[i][j]==1) {
                        continue;
                    }
					
                    que.offer(new QueData(i, j));
                    visit_pan[i][j]=true;
                    finished_cnt++;
                                        
                    while( !que.isEmpty() ) {
                    	
                        QueData org_que = (QueData)que.poll();
                        org_i = org_que.i;
                        org_j = org_que.j;
                        
                        for (int k=0; k<4; k++) {
                            temp_i = org_i+move_1[k];
                            temp_j = org_j+move_2[k];
                            if( temp_i<0 || temp_i>=N || temp_j<0 || temp_j>=M ) {
                                continue;
                            }
                            if( visit_pan[temp_i][temp_j] ) {
                                continue;
                            }
                            
                            if(base_pan[temp_i][temp_j]==1) {
                                temp_pan[temp_i][temp_j] = temp_pan[temp_i][temp_j]+1;
                                
                            }else {
                                que.offer(new QueData(temp_i, temp_j));
                                visit_pan[temp_i][temp_j] = true;
                                finished_cnt++;
                            }
                        }
                    }

                }
            }
			
			// 2칸 이상 공기에 노출된 치즈를 녹임
            for (int i=0; i<N; i++) {
            	for(int j=0;j<M;j++) {
            		if (temp_pan[i][j]>=2) {
            			finished_cnt++;
            			base_pan[i][j]=0;
            		}
            	}
            }
            hour++;	
        }

        System.out.print(hour);

    }
}