백준 2638 - 치즈
Updated:
Java
2638 번 - 치즈
문제
접근 방법
BFS를 사용하여 치즈가 없는 빈 공간이 외부인지 내부인지 확인한다.
문제에서 ‘모눈종이의 맨 가장자리에는 치즈가 놓이지 않는 것으로 가정’하므로,
(0,0) 점에서 시작하여 치즈로 막혀있지 않는 모든 곳을 탐색하면, 외부를 찾을 수 있다.
이후 n * m 공간을 탐색하며 치즈가 있을 시, 2개 이상의 외부가 존재 여부를 확인하여 치즈를 지운다.
코드
import java.util.*;
import java.io.*;
public class Main {
static int n, result, m;
static int totalC;
static int[][] map;
static boolean[][] isOut;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk = new StringTokenizer(br.readLine());
n = stoi(stk.nextToken());
m = stoi(stk.nextToken());
map = new int[n][m];
for(int i = 0; i < n; i++) {
stk = new StringTokenizer(br.readLine());
for(int j = 0; j < m; j++) {
map[i][j] = stoi(stk.nextToken());
if(map[i][j] == 1)
totalC++;
}
}
int curCh = 0, turn = 0, ny, nx, cntOut;
// 치즈가 다 녹을 때 까지 진행
while(curCh != totalC) {
isOut = new boolean[n][m];
BFS();
for(int y = 0; y < n; y++) {
for(int x = 0; x < m; x++) {
// 해당 위치에 치즈가 있을 때
if(map[y][x] == 1) {
cntOut = 0;
// 해당 위치의 상하좌우가 외부 일 시
for(int i = 0; i < 4; i++) {
ny = y + dy[i];
nx = x + dx[i];
if(isOut[ny][nx]) {
cntOut++;
}
}
// 외부가 2개 이상일 때
if(cntOut >= 2) {
map[y][x] = 0; // 이 장소의 치즈는 사라진다.
curCh++;
}
}
}
}
turn++;
}
System.out.println(turn);
br.close();
}
static int[] dy = {-1, 1, 0, 0};
static int[] dx = {0, 0, -1, 1};
// 빈 공간이 외부인지 확인하는 메서드
private static void BFS() {
Queue<int[]> queue = new LinkedList<>();
int[] q;
int y,x, ny, nx;
queue.add(new int[] {0,0});
isOut[0][0] = true;
while(!queue.isEmpty()) {
q = queue.poll();
y = q[0];
x = q[1];
for(int i = 0; i < 4; i++) {
ny = y + dy[i];
nx = x + dx[i];
if(isIn(ny,nx) && !isOut[ny][nx] && map[ny][nx] == 0) {
isOut[ny][nx] = true;
queue.add(new int[] {ny, nx});
}
}
}
}
// 주어진 범위 안에 있는가
public static boolean isIn(int y, int x){
if(y < 0 || y >= n || x < 0 || x >= m)
return false;
return true;
}
static int stoi(String str) {
return Integer.parseInt(str);
}
}