빙산
백준 2573: 빙산
풀이
BFS를 사용하여 빙산을 녹이고,
DFS를 사용하여 빙산이 두 덩어리 이상으로 분리 되는지를 확인
- dfs(int r, int c, boolean[][] visited)
- r : 2차원 배열의 행
- c : 2차원 배열의 열
- visited : 방문체크 배열
소스코드
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 Main {
static class Node {
int r, c, year;
Node(int r, int c, int year) {
this.r = r;
this.c = c;
this.year = year;
}
}
static int[] dr = { -1, 1, 0, 0 };
static int[] dc = { 0, 0, -1, 1 };
static int N;
static int M;
static int[][] map;
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());
}
}
Queue<Node> queue = new LinkedList<>();
int year = 0;
int cnt = 0;
boolean ch =false;
while (cnt < 2) { //두 덩어리 이상으로 분리 될때까지
boolean[][] check = new boolean[N][M];
year++;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
//빙산을 다 큐에 담자
if (map[i][j] != 0)
queue.add(new Node(i, j, year));
}
}
while (!queue.isEmpty()) {
Node node = queue.poll();
year = node.year;
for (int d = 0; d < 4; d++) {
int nr = node.r + dr[d];
int nc = node.c + dc[d];
if (nr >= 0 && nc >= 0 && nr < N && nc < M) {
if (map[nr][nc] == 0 && !check[nr][nc]) {
map[node.r][node.c] = map[node.r][node.c] - 1; //빙산을 녹여
if(map[node.r][node.c]<0) //빙산을 녹여서 0보다 작아지면
map[node.r][node.c]=0; //그 자리는 0으로 만들어줌
check[node.r][node.c] = true;
}
}
}
}
boolean[][] visited = new boolean[N][M];
cnt=0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (map[i][j] != 0 && !visited[i][j]) {
visited[i][j]=true;
cnt++;
dfs(i, j, visited);
}
}
}
int zerocnt=0; //0의 개수를 세기 위한 변수
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(map[i][j]==0)
zerocnt++;
}
}
if(zerocnt==N*M) //배열의 전체가 0이면(빙산이 모두 녹은 것) 끝내기
break;
}
if(cnt<2)
System.out.println("0");
else if(cnt>=2)
System.out.println(year);
}
static void dfs(int r, int c, boolean[][] visited) {
for (int d = 0; d < 4; d++) {
int nr = r + dr[d];
int nc = c + dc[d];
if (nr >= 0 && nc >= 0 && nr < N && nc < M && !visited[nr][nc]&&map[nr][nc]!=0) {
visited[nr][nc] = true;
dfs(nr, nc, visited);
}
}
}
}