


-Code
import java.io.*;
import java.util.*;
public class BOJ2573 {
static class Pos {
int row, col;
public Pos (int row, int col) {
this.row = row;
this.col = col;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pos pos = (Pos) o;
return row == pos.row && col == pos.col;
}
@Override
public int hashCode() {
return Objects.hash(row, col);
}
}
static int[][] map;
static boolean[][] visited;
static int rowSize;
static int colSize;
static int[] dRow = {-1, 0, 1, 0};
static int[] dCol = {0, -1, 0, 1};
public static void main(String[] args) throws IOException {
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
rowSize = Integer.parseInt(st.nextToken());
colSize = Integer.parseInt(st.nextToken());
// 빙산 셋팅
map = new int[rowSize][colSize];
Map<Pos, Integer> posHeight = new HashMap<>();
for (int r = 0; r < rowSize; r++) {
st = new StringTokenizer(br.readLine());
for (int c = 0; c < colSize; c++) {
map[r][c] = Integer.parseInt(st.nextToken());
// 빙산 높이 저장
if (map[r][c] != 0) {
posHeight.put(new Pos(r, c), map[r][c]);
}
}
}
int answer = 0;
while(true) {
// 현재 빙산 덩어리 갯수 구하기
int cnt = 0;
visited = new boolean[rowSize][colSize];
for (Pos pos : posHeight.keySet()) {
if (!visited[pos.row][pos.col]) {
cnt++;
icebergCheck(pos);
}
}
// 2개 이상이면 탈출
if (cnt >= 2) {
break;
}
// 다 녹았는데 안되면 탈출
if (cnt == 0) {
answer = 0;
break;
}
// 녹은 빙산 구하기
ArrayList<Pos> meltList = new ArrayList<>();
for (Pos pos : posHeight.keySet()) {
// 주변 인접 바다만큼 감소량 구하기
int meltCnt = 0;
for (int i = 0; i < 4; i++) {
int row = pos.row + dRow[i];
int col = pos.col + dCol[i];
if (map[row][col] == 0) {
meltCnt++;
}
}
// 해당 빙산의 높이가 녹는 수보다 작으면 삭제
int nowHeight = posHeight.get(pos);
if (nowHeight <= meltCnt) {
meltList.add(pos);
} else {
// 녹지 않는 다면 높이 감소
int changeHeight = nowHeight - meltCnt;
posHeight.put(pos, changeHeight);
map[pos.row][pos.col] = changeHeight;
}
}
// 한번에 녹이기
for (Pos meltPos : meltList) {
posHeight.remove(meltPos);
map[meltPos.row][meltPos.col] = 0;
}
answer++;
}
System.out.println(answer);
}
private static void icebergCheck(Pos start) {
// BFS 초기 셋팅
visited[start.row][start.col] = true;
Deque<Pos> posDeq = new ArrayDeque<>();
posDeq.addLast(start);
// 탐색
while (!posDeq.isEmpty()) {
Pos now = posDeq.pollFirst();
for (int i = 0; i < 4; i++) {
int nextRow = now.row + dRow[i];
int nextCol = now.col + dCol[i];
if (isMove(nextRow, nextCol) && !visited[nextRow][nextCol]) {
visited[nextRow][nextCol] = true;
posDeq.addLast(new Pos(nextRow, nextCol));
}
}
}
}
private static boolean isMove(int row, int col) {
return (0 <= row && row < rowSize) &&
(0 <= col && col < colSize) &&
(map[row][col] != 0);
}
}
풀면서 큰 틀은 맞았지만 2가지 문제점이 있었습니다.
- 녹은 빙산 처리를 한번 사이클이 돌아간 뒤에 하지 않으면 다른 빙산이 녹는 것에 영향이 가 문제가 생기게 됩니다.
- 처음에 maxHeight를 만들고 그 횟수만큼 반복했는데 이 방식은 최대 높이의 빙산이 안 녹을 입력이 존재해 while로 다 녹을 때까지 반복해야 합니다.
이 2가지 문제를 해결하니 문제를 풀수 있었지만 거의 다 풀었는데 위와 같은 부분을 간과하여 아쉬웠습니다.
'Beakjoon&프로그래머스 > Java' 카테고리의 다른 글
| [백준/Java] 13549번 숨바꼭질 3 (0) | 2026.01.25 |
|---|---|
| [백준/Java] 1812번 사탕 (0) | 2026.01.25 |
| [백준/Java] 13913번 숨바꼭질 4 (0) | 2026.01.24 |
| [백준/Java] 7798번 Hotel (0) | 2026.01.24 |
| [백준/Java] 6593번 상범 빌딩 (0) | 2026.01.24 |