N*M의 모눈종이 위에 치즈가 표시되어있고, 이 외의 빈칸은 공기이다. 이때 실내 온도의 공기와 접촉한 치즈는 한 시간만에 녹아버린다. 이때 치즈 내부에 존재하는 빈 공간은 외부 공기와 접촉하지 않은 것으로 가정한다. 또, 모눈종이의 맨 가장자리는 치즈가 놓이지 않음!
이때 주어진 치즈가 모두 녹는데 걸리는 정확한 시간을 출력하시오~
문제를 꼼꼼히 읽자..
치즈 내부에 존재하는 빈 공간과 외부 공기를 따로 구분해주고, 치즈가 녹을 때마다 빈 공간인지 외부 공기인지를 체크해줘야했다.
문제 다 풀고 봐서 다시 풀었다
ㅋ
내부 공기 - 0
치즈 - 1
외부 공기 - 2
녹은 치즈 - 3
checkExternal()
함수로 외부 공기를 체크해준다.2
로 표시한다.dfs()
에서는 녹을 가능성이 있는 치즈를 3
으로 바꿔주고 count--
해주면서 치즈의 개수를 줄여준다.왜 3으로 바꿔주느냐?!
=> 바로 외부 공기인 2값으로 바꿔주면 한 시간 안(이번 텀)에 녹지 말아야 할 치즈가 녹아버림
isMelt()
함수로 한다.import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ_2638 {
static int n, m, count, answer;
static int[][] board;
static boolean[][] visited;
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
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());
count = 0;
answer = 0;
board = new int[n][m];
visited = new boolean[n][m];
// 치즈 1
// 바깥 공기 2
// 내부 공기 0
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
int value = Integer.parseInt(st.nextToken());
board[i][j] = value;
if (value == 1) count++;
}
}
checkExternalAir(0, 0);
while (count != 0) {
visited = new boolean[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (board[i][j] == 1 && !visited[i][j]) dfs(i, j);
}
}
visited = new boolean[n][m];
checkExternalAir(0, 0);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
board[i][j] = board[i][j] == 3 ? 2 : board[i][j];
}
}
answer++;
}
System.out.println(answer);
}
// 외부와 접촉한 공기 '2'로 표시
static void checkExternalAir(int x, int y) {
visited[x][y] = true;
board[x][y] = 2;
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
if (visited[nx][ny] || board[nx][ny] == 1) continue;
board[nx][ny] = 2;
checkExternalAir(nx, ny);
}
}
static void dfs(int x, int y) {
visited[x][y] = true;
if (board[x][y] == 1 && isMelt(x, y)) {
--count;
board[x][y] = 3; // 녹은 치즈는 3으로 바꿔준다 (0으로 바꾸면 언제 녹았는지 구분 불가)
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
if (visited[nx][ny] || board[nx][ny] == 0) continue;
dfs(nx, ny);
}
}
static boolean isMelt(int x, int y) {
int air = 0;
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
if (board[nx][ny] == 2) ++air;
}
return air >= 2;
}
}