Algorithm/BFS & DFS
[๋ฐฑ์ค, Java] 2573๋ฒ : ๋น์ฐ
Zayson
2022. 5. 2. 17:57
๐ ๋ฌธ์ ๋งํฌ
https://www.acmicpc.net/problem/2573
๐ฎ ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ
๋น์ฐ์ ๋ น์ฌ์ผ ํ๋์ง ํ๋จ์ ํ๋ ๋ฐฐ์ด๊ณผ ์ค์ ๋ก ์ธ์ ํ ๋ฐ๋ค๋ฅผ ์ฒดํฌํ ํ ๋ น์ ํ์ ๋น์ฐ ์ํ๋ฅผ ์ ์ฅํ๋ ๋ฐฐ์ด ๋๊ฐ๋ฅผ ์ฌ์ฉํด์ ํด๊ฒฐํ๋ค.
๋น์ฐ ์ํ๋ฅผ ๋ น์ด๋ ๋ฐฐ์ด์ ํ์ฌ ํด์ ๋น์ฐ ๋ฐฐ์ด์ ๋ณต์ฌํ ๋ฐฐ์ด์ด๋ค.
- ๊ธฐ์กด ๋น์ฐ ๋ฐฐ์ด์ ๋ น์ ํ ๋น์ฐ ์ํ๋ฅผ ์ ์ฅํ๋ ๋ฐฐ์ด๋ก ์ฌ์ฉํ๊ธฐ ์ํด ๋ณต์ฌํ๋ค.
- ๊ธฐ์กด ๋น์ฐ ๋ฐฐ์ด์ ์ด์ฉํด์ ๋น์ฐ์ด ๋จ์์๊ณ , ์ํ์ข์ฐ ์ธ์ ํ ๋ถ๋ถ์ ๋ฐ๋ค๊ฐ ์๋์ง ํ๋จํ๋ค.
- ์ด ๋, ๋จ ํ๋๋ก ๋น์ฐ์ด ๋จ์์์ง ์์๋ค๋ฉด, ๋น์ฐ์ด ๋ค ๋ น์๋ ๊น์ง ๋ ๋ฉ์ด๋ฆฌ ์ด์์ผ๋ก ๋น์ฐ์ด ๋๋ ์ง์ง ์์๊ธฐ ๋๋ฌธ์ 0์ ๋ฆฌํดํ๊ณ ์ข ๋ฃํ๋ค.
- ์ํ์ข์ฐ ์ธ์ ํ ๋ฐ๋ค์ ๊ฐ์ ๋งํผ ๋น์ฐ์ ํฌ๊ธฐ๋ฅผ ๋ น์ฌ์ค๋ค.
- ํ์ฌ ํด์ ๋ น์ผ ์ ์๋ ๋น์ฐ์ ๋ชจ๋ ์ฒดํฌํ๋ค๋ฉด, ํ์ฌ ํด๋ฅผ ์ฆ๊ฐ ์ํจ๋ค.
- ๋น์ฐ์ด ๋๋ฉ์ด๋ฆฌ๋ก ๋๋์ด ์ก๋์ง ํ์ธํ๋ค.
- BFS๋ฅผ ์ด์ฉํด ํ์ฌ ๋น์ฐ์ด ๋๋์ด์ก๋์ง ํ์ธํ๋ค.
- ํ์ฌ ์ํ์ ๋น์ฐ์ ๋ํด์ BFS๋ฅผ ์งํํ๊ธฐ ๋๋ฌธ์ ํ ๋ฒ ์ด์ด์ ธ์๋ ๋น์ฐ ๋ฉ์ด๋ฆฌ๋ฅผ ๊ตฌํ๋ค๋ฉด, ์ดํ์ ๋ฐฉ๋ฌธํ์ง ์์ ๋น์ฐ์ด ๋จ์์๋ค๋ฉด BFS ๋ก์ง์ ํธ์ถํ์ง ์๊ณ ๋ฐ๋ก ๋ ๋ฉ์ด๋ฆฌ ์ด์์ผ๋ก ๋๋์ด์ก๋ค๊ณ ํ๋จ์ด ๊ฐ๋ฅํ๋ค.
- ๋ ๋ฉ์ด๋ฆฌ ์ด์์ผ๋ก ๋น์ฐ์ด ๋ น์์ง์ง ์์๋ค๋ฉด, ๋ค์ ํด์ ๊ธฐ์กด ๋น์ฐ ๋ฐฐ์ด์ด ํ์ฌ ๋ น์ธ ์ํ์ ๋ฐฐ์ด ๊ฐ์ผ๋ก ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ ์ฌ๋ณต์ฌ๋ฅผ ํด์ค๋ค.
์ด๋ฌํ ๋ก์ง์ ํ๋ํ๋ ๊ตฌํํ๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
๐ฉ Java ์ฝ๋
package com.algorithm.Baekjoon;
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_2573_๋น์ฐ {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[][] iceberg = new int[N][M];
for(int row = 0; row < N; row++) {
st = new StringTokenizer(br.readLine());
for(int col = 0; col < M; col++) {
iceberg[row][col] = Integer.parseInt(st.nextToken());
}
}
int rst = getMinYear(N, M, iceberg);
System.out.println(rst);
br.close();
}
private static final int[] DX = {1, -1, 0, 0};
private static final int[] DY = {0, 0, 1, -1};
private static int getMinYear(int n, int m, int[][] iceberg) {
/**
* 1. ๊ธฐ์กด ๋น์ฐ ๋ฐฐ์ด์ ์๋ก์ด ๋น์ฐ ๋ฐฐ์ด๋ก ํ๋ ๋ณต์ฌํ๊ธฐ
* 2. ๊ธฐ์กด ๋น์ฐ ๋ฐฐ์ด์ ์ด์ฉํด ๋จ์ ๋จ์์๋ ๋น์ฐ์ ์ํ์ข์ฐ์ ๋ฐ๋ค๊ฐ ์ธ์ ํด์๋์ง ์ฒดํฌ
* 3. ์๋ก ๋ณต์ฌํ ๋น์ฐ ๋ฐฐ์ด์ ์ธ์ ํ ๋ฐ๋ค ๊ฐ์ ๋งํผ ๋
น์ด๊ธฐ
* 3-1. ํ์ฌ ํด์ ํ๋ฒ๋ ๋น์ฐ์ ๋
น์ด์ง ์์ ๊ฒฝ์ฐ ๋ค ๋
น์์ง๋ง ๋ ๋ฉ์ด๋ฆฌ๋ก ๋๋ ์ง์ง ์์ ๊ฒฝ์ฐ๋ฏ๋ก return 0;
* 4. ํ์ฌ ํด์ ๋
น์ผ ์ ์๋ ๋น์ฐ์ ๋
น์์ผ๋ฏ๋ก, ํ์ฌ ํด๋ฅผ 1 ์ฆ๊ฐ
* 5. ๋น์ฐ์ด ๋ ๋ฉ์ด๋ฆฌ ์ด์์ผ๋ก ๋๋์ด์ก๋์ง ํ๋จํ๊ธฐ
* 6. ๋๋์ด ์ง์ง ์์ ๊ฒฝ์ฐ ์๋ก์ด ๋ฐฐ์ด์ ๋ค์ ํด์ ๊ธฐ์กด ๋ฐฐ์ด๋ก ์ฌ์ฉํ๊ธฐ ์ํด ๋ณต์ฌ
*/
int year = 0;
while(true) {
// 1. ๊ธฐ์กด ๋ฐฐ์ด ์๋ก์ด ๋ฐฐ์ด๋ก ๋ณต์ฌ
int[][] copyIceberg = copyArray(n,m, iceberg);
boolean remainIceberg = false; // ํ์ฌ ํด์ ๋จ์ ๋น์ฐ์ด ์๋์ง ํ๋จํ๊ธฐ ์ํด
for(int row =0; row < n; row++) {
for(int col = 0; col < m; col++) {
// 2. ๋จ์์๋ ๋น์ฐ์ด ์๊ณ ์ํ์ข์ฐ ๋ฐ๋ค ํ๋จ
if(iceberg[row][col] != 0) {
int meltCount = 0;
for(int direction = 0; direction < 4; direction++) {
int checkRow = DX[direction] + row;
int checkCol = DY[direction] + col;
if(checkBound(checkRow, checkCol, n,m) && iceberg[checkRow][checkCol] == 0) {
meltCount++; // ์ํ์ข์ฐ์ ๋ฐ๋ค ๊ฐ์ ๊ตฌํ๊ธฐ
}
}
// 3. ์๋ก ๋ณต์ฌํ ๋น์ฐ ๋ฐฐ์ด์ ์ธ์ ํ ๋ฐ๋ค ๊ฐ์ ๋งํผ ๋
น์ด๊ธฐ
copyIceberg[row][col] = Math.max(copyIceberg[row][col] - meltCount, 0); // 0 ๋ณด๋ค ํฌ๋ฉด ๋น์ฐ ๋
น์ธ ํฌ๊ธฐ ์๋๋ฉด ๋ค ๋
น์ ๊ฒฝ์ฐ
remainIceberg = true; // ํ๋ฒ์ด๋ผ๋ ๋น์ฐ์ ๋
น์์ผ๋ฉด ๋จ์ ๋น์ฐ์ด ์์๋ค๋ ๋ป
}
}
}
// 3-1. ๋น์ฐ์ด ๋ค ๋
น์์ง๋ง ๋ ๋ฉ์ด๋ฆฌ๋ก ์๋๋ ์ง ๊ฒฝ์ฐ
if(!remainIceberg) {
year = 0;
break;
}
// 4. ๋น์ฐ ๋
น์ด๊ณ ์ผ๋
๋ณด๋ด๊ธฐ
year++;
// 5. ๋น์ฐ์ด ๋๊ฐ๋ ์ด์์ผ๋ก ๋๋ ์ก๋์ง ํ๋จ
if(isDivide(copyIceberg, n,m)) break;
// 6. ๋ค ๋
น์ง ์์ ๊ฒฝ์ฐ ๊ธฐ์กด ๋ฐฐ์ด์ ๋จ์ ๋น์ฐ ๋ฐฐ์ด๋ก ๋ณต์ฌ
iceberg = copyArray(n, m, copyIceberg);
}
return year;
}
private static boolean isDivide(int[][] copyIceberg, int n, int m) {
boolean[][] visited = new boolean[n][m];
boolean isDivide = false;
for(int row =0; row < n; row++) {
for(int col = 0; col < m; col++) {
if(!visited[row][col] && copyIceberg[row][col] != 0) {
if(isDivide) return true; // ์ด์ด์ง ๋น์ฐ ํ๋ฒ ํ์ํ ๊ฒฝ์ฐ ๋ค์ ๋ฐฉ๋ฌธํ์ง ์์ ๋น์ฐ์ ๋๋ ์ง ๊ฒฝ์ฐ์ด๊ธฐ ๋๋ฌธ์ true
bfs(copyIceberg, row, col, n, m, visited);
isDivide = true; // ํ๋์ ์ด์ด์ง ๋น์ฐ์ ๊ตฌํจ
}
}
}
return false;
}
private static void bfs(int[][] copyIceberg, int row, int col, int n, int m, boolean[][] visited) {
// ์ด์ด์ง ๋น์ฐ ์ฒดํฌํ๊ธฐ
Queue<Point> queue = new LinkedList<>();
queue.add(new Point(row, col));
while(!queue.isEmpty()) {
Point curPoint = queue.poll();
int curRow = curPoint.getRow();
int curCol = curPoint.getCol();
if(visited[curRow][curCol]) continue;
visited[curRow][curCol] = true;
for(int direction = 0; direction < 4; direction++) {
int nextRow = curRow + DX[direction];
int nextCol = curCol + DY[direction];
if(checkBound(nextRow,nextCol, n,m) && !visited[nextRow][nextCol] && copyIceberg[nextRow][nextCol] != 0) {
queue.add(new Point(nextRow, nextCol));
}
}
}
}
private static boolean checkBound(int checkRow, int checkCol, int n, int m) {
return checkRow >= 0 && checkRow < n && checkCol >= 0 && checkCol < m;
}
private static int[][] copyArray(int n, int m, int[][] iceberg) {
int[][] copyIceberg = new int[n][m];
for(int row = 0; row < n; row++) {
for(int col = 0; col < m; col++) {
copyIceberg[row][col] = iceberg[row][col];
}
}
return copyIceberg;
}
static class Point {
private int row;
private int col;
public Point(int row, int col) {
this.row = row;
this.col = col;
}
public int getRow() {
return row;
}
public int getCol() {
return col;
}
}
}
๋ฐ์ํ