성능 요약
메모리: 25000 KB, 시간: 404 ms
분류
너비 우선 탐색, 깊이 우선 탐색, 그래프 이론, 그래프 탐색, 구현
제출 일자
2024년 8월 24일 20:36:46
문제 설명
<p>지구 온난화로 인하여 북극의 빙산이 녹고 있다. 빙산을 그림 1과 같이 2차원 배열에 표시한다고 하자. 빙산의 각 부분별 높이 정보는 배열의 각 칸에 양의 정수로 저장된다. 빙산 이외의 바다에 해당되는 칸에는 0이 저장된다. 그림 1에서 빈칸은 모두 0으로 채워져 있다고 생각한다.</p>
<table class="table table-bordered td-center table-center-35 td-width-5"> <tbody> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td>2</td> <td>4</td> <td>5</td> <td>3</td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td>3</td> <td> </td> <td>2</td> <td>5</td> <td>2</td> <td> </td> </tr> <tr> <td> </td> <td>7</td> <td>6</td> <td>2</td> <td>4</td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </tbody> </table>
<p style="text-align: center;">그림 1. 행의 개수가 5이고 열의 개수가 7인 2차원 배열에 저장된 빙산의 높이 정보</p>
<p><span style="line-height:1.6em">빙산의 높이는 바닷물에 많이 접해있는 부분에서 더 빨리 줄어들기 때문에, 배열에서 빙산의 각 부분에 해당되는 칸에 있는 높이는 일년마다 그 칸에 동서남북 네 방향으로 붙어있는 0이 저장된 칸의 개수만큼 줄어든다. 단, 각 칸에 저장된 높이는 0보다 더 줄어들지 않는다. 바닷물은 호수처럼 빙산에 둘러싸여 있을 수도 있다. 따라서 그림 1의 빙산은 일년후에 그림 2와 같이 변형된다.</span></p>
<p>그림 3은 그림 1의 빙산이 2년 후에 변한 모습을 보여준다. 2차원 배열에서 동서남북 방향으로 붙어있는 칸들은 서로 연결되어 있다고 말한다. 따라서 그림 2의 빙산은 한 덩어리이지만, 그림 3의 빙산은 세 덩어리로 분리되어 있다.</p>
<table class="table table-bordered td-center table-center-35 td-width-5"> <tbody> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td>2</td> <td>4</td> <td>1</td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td>1</td> <td> </td> <td>1</td> <td>5</td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td>5</td> <td>4</td> <td>1</td> <td>2</td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </tbody> </table>
<p style="text-align: center;">그림 2</p>
<table class="table table-bordered td-center table-center-35 td-width-5"> <tbody> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td>3</td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td>4</td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td>3</td> <td>2</td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </tbody> </table>
<p style="text-align: center;">그림 3</p>
<p>한 덩어리의 빙산이 주어질 때, 이 빙산이 두 덩어리 이상으로 분리되는 최초의 시간(년)을 구하는 프로그램을 작성하시오. 그림 1의 빙산에 대해서는 2가 답이다. 만일 전부 다 녹을 때까지 두 덩어리 이상으로 분리되지 않으면 프로그램은 0을 출력한다.</p>
입력
<p>첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을 나타내는 M개의 정수가 한 개의 빈 칸을 사이에 두고 주어진다. 각 칸에 들어가는 값은 0 이상 10 이하이다. 배열에서 빙산이 차지하는 칸의 개수, 즉, 1 이상의 정수가 들어가는 칸의 개수는 10,000 개 이하이다. 배열의 첫 번째 행과 열, 마지막 행과 열에는 항상 0으로 채워진다.</p>
출력
<p>첫 줄에 빙산이 분리되는 최초의 시간(년)을 출력한다. 만일 빙산이 다 녹을 때까지 분리되지 않으면 0을 출력한다.</p>
풀이
javaimport java.util.*; import java.io.*; class Main { static int row; static int col; static int[][] map; static int[][] visited; static int[][] melt; static int[] dx = {1, -1, 0, 0}; static int[] dy = {0, 0, 1, -1}; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); row = Integer.parseInt(st.nextToken()); col = Integer.parseInt(st.nextToken()); map = new int[row][col]; visited = new int[row][col]; melt = new int[row][col]; for (int i=0; i<row; i++) { // 빙산 배열 st= new StringTokenizer(br.readLine()); for(int j=0; j<col; j++) { map[i][j]= Integer.parseInt(st.nextToken()); } } answer(); } static void answer() { int year= 0; while (true) { int count= 0; for (int i=0; i<row; i++) { for (int j=0; j<col; j++) { if(visited[i][j]= 0 && map[i][j] = 0) { // 방문하지 않았고 빙산이 있는 경우 dfs(i, j); count++; } } } // 빙산이 모두 녹은 경우 if (count= 0) { System.out.println(0); break; } else if (count >= 2) { // 빙산 덩어리가 2개 이상인 경우 System.out.println(year); break; } melting(); year++; } } // dfs static void dfs(int x, int y) { visited[x][y] = 1; for(int i=0; i<4; i++) { int nx= x + dx[i]; int ny= y + dy[i]; if (0<=nx && nx<row && 0<=ny && ny<col) { // 1년 후에 녹는 빙산의 양 if(map[nx][ny]= 0) melt[x][y]++; if (visited[nx][ny=0 && map[nx][ny]=0) // 방문하지 않았고 빙산이 있는 경우 dfs(nx, ny); } } } // 빙산 녹임 static void melting() { for(int i=0; i<row; i++) { for(int j=0; j<col; j++) { map[i][j] = melt[i][j]; // 빙산 높이에서 녹은 양 뺌 if(map[i][j] < 0) map[i][j]= 0; // 높이가 음수가 되면 0으로 설정 visited[i][j]= 0; melt[i][j]= 0; } } } }