알고리즘 문제 풀이

백준 2638 치즈 (Java 자바)

superbono 2021. 4. 4. 17:13
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class bj2638_치즈 {
	static class Data{
		int x;
		int y;
		
		public Data(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}
	static int N, M;
	static int map[][];
	static boolean visited[][];
	static Queue <Data> q;
	// 상 하 좌 우 
	static int dr[] = {-1, 1, 0, 0};
	static int dc[] = {0, 0, -1, 1};
	static int res;
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		
		map = new int[N][M];
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for (int j = 0; j < M; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		while(true) {
			// 먼저 공기랑 닿아있는 치즈 구하고
			bfs();
			if(isMelted()) 
				res++;
			else break;
		}
		System.out.println(res);
	}
	
	static boolean isMelted() {
		boolean isAvailable = false;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				// 외부와 2번 이상 닿은 치즈가 있을 경우 
				if(map[i][j] >= 3) {
					// 치즈 녹여주고 공기로 만든다
					map[i][j] = 0;
					// 치즈 녹일 수 있으니까 
					isAvailable = true;
				}
				// 외부(공기)와 한번만 닿았었으면 그냥 원래 치즈로 돌려놓기
				if(map[i][j] == 2) {
					map[i][j] = 1;
				}
			}
		}
		
		return isAvailable;
	}
	
	static void bfs() {
		q = new LinkedList<>();
		// 매번 새로 만들어주기
		visited = new boolean [N][M];
		visited[0][0] = true;
		q.offer(new Data(0, 0));
		
		Data cur = null;
		while(!q.isEmpty()) {
			cur = q.poll();
			
			for (int dir = 0; dir < 4; dir++) {
				int nx = cur.x + dr[dir];
				int ny = cur.y + dc[dir];
				
				if(nx < 0 || ny < 0 || nx >= N || ny >= M)
					continue;
				if(visited[nx][ny]) continue;
				// 공기로만 도니까 치즈로는 가지 않는다
				if(map[nx][ny] >= 1) {
					map[nx][ny]++;
					continue;
				}
				
				visited[nx][ny] = true;
				q.offer(new Data(nx, ny));
			}
		}
	}
}