-
2573 : 빙산Solve Algorithms/BFS, DFS 2020. 4. 28. 16:58728x90
출처 : https://www.acmicpc.net/problem/2573
문제
지구 온난화로 인하여 북극의 빙산이 녹고 있다. 빙산을 그림 1과 같이 2차원 배열에 표시한다고 하자. 빙산의 각 부분별 높이 정보는 배열의 각 칸에 양의 정수로 저장된다. 빙산 이외의 바다에 해당되는 칸에는 0이 저장된다. 그림 1에서 빈칸은 모두 0으로 채워져 있다고 생각한다.
빙산의 높이는 바닷물에 많이 접해있는 부분에서 더 빨리 줄어들기 때문에, 배열에서 빙산의 각 부분에 해당되는 칸에 있는 높이는 일년마다 그 칸에 동서남북 네 방향으로 붙어있는 0이 저장된 칸의 개수만큼 줄어든다. 단, 각 칸에 저장된 높이는 0보다 더 줄어들지 않는다. 바닷물은 호수처럼 빙산에 둘러싸여 있을 수도 있다.
한 덩어리의 빙산이 주어질 때, 이 빙산이 두 덩어리 이상으로 분리되는 최초의 시간(년)을 구하는 프로그램을 작성하시오. 그림 1의 빙산에 대해서는 2가 답이다. 만일 전부 다 녹을 때까지 두 덩어리 이상으로 분리되지 않으면 프로그램은 0을 출력한다.
입력
첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을 나타내는 M개의 정수가 한 개의 빈 칸을 사이에 두고 주어진다. 각 칸에 들어가는 값은 0 이상 10 이하이다. 배열에서 빙산이 차지하는 칸의 개수, 즉, 1 이상의 정수가 들어가는 칸의 개수는 10,000 개 이하이다. 배열의 첫 번째 행과 열, 마지막 행과 열에는 항상 0으로 채워진다.
출력
첫 줄에 빙산이 분리되는 최초의 시간(년)을 출력한다. 만일 빙산이 다 녹을 때까지 분리되지 않으면 0을 출력한다.
접근
- 그림 1에서 (1, 1) 칸에 있는 '2'는, 인접한 0의 개수가 2개이므로, 1년 후 0이된다.
- 글림 1에서 (1, 2) 칸에 있는 '4'는, 인접한 0의 개수가 2개이다. 이 때, (1, 1)이 0이 되기 때문에 (1, 2) 칸의 인접한 0의 개수가 3이라고 착각할 수 있다.
- 이 것을 보완하기 위해, tmp 배열을 생성한다.
- tmp에는 (i, j)에 인접한 0의 개수를 저장한다.
- 이 후, year() 함수에서 map[i][j]에서 tmp[i][j]를 뺀다.
- 이 부분만 주의하고, 나머지는 기존의 BFS문제와 동일하다.
코드
class Polar {int x, y;public Polar(int x, int y) {this.x = x;this.y = y;}}public class Main {static int N, M, BFS_Count, YEAR_Count=-1;static int[][] map;static int[][] visit;static int[][] tmp;static int[] dx = { -1, 0, 1, 0 };static int[] dy = { 0, -1, 0, 1 };static Queue<Polar> q = new LinkedList<Polar>();public static void BFS(Polar p) {q.add(p);visit[p.x][p.y] = 1;while (!q.isEmpty()) {Polar t = q.poll();int X = t.x;int Y = t.y;for (int i = 0; i < 4; i++) {int nextX = X + dx[i];int nextY = Y + dy[i];if (nextX >= 0 && nextY >= 0 && nextX < N && nextY < M) {if (map[nextX][nextY] == 0) {tmp[X][Y]++;}if (map[nextX][nextY] > 0) {if (visit[nextX][nextY] == 0) {q.add(new Polar(nextX, nextY));visit[nextX][nextY] = 1;}}}}}}public static int Year() {for (int i = 0; i < N; i++) {for (int j = 0; j < M; j++) {map[i][j] -= tmp[i][j];if (map[i][j] < 0)map[i][j] = 0;}}visit = new int[N][M];tmp = new int[N][M];return 1;}public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));StringTokenizer st = new StringTokenizer(br.readLine(), " ");N = Integer.parseInt(st.nextToken());M = Integer.parseInt(st.nextToken());map = new int[N][M];visit = new int[N][M];tmp = 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_Count = 0;YEAR_Count += Year();for (int i = 0; i < N; i++) {for (int j = 0; j < M; j++) {if (map[i][j] > 0 && visit[i][j] == 0) {BFS(new Polar(i, j));BFS_Count++;}}}if (BFS_Count == 0) {bw.write("0\n");break;} else if (BFS_Count >= 2) {break;}}}}728x90'Solve Algorithms > BFS, DFS' 카테고리의 다른 글
1987 : 알파벳 (0) 2020.05.03 2589 : 보물섬 (0) 2020.04.28 3187 : 양치기꿍 (0) 2020.04.24 4179 : 불! (0) 2020.04.24 10026 : 적록 색약 (0) 2020.04.23