반응형
백준 2573번 문제 - 빙산
2573번: 빙산
첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을
www.acmicpc.net
문제 분석
- 빙산 N * N 개의 높이를 배열 형태로 입력 받았을 때, 가장 많은 빙산 덩어리가 2개 이상으로 분리되는 최초의 시간을 출력해라.
- 빙산이 없는 공간은 0으로 입력된다.
- 빙산은 주변에 빙산이 없는 수만큼 녹는다 (주변에 0이 있는 수만큼)
- 빙산 덩어리 : 빙산으로 이루어진 덩어리
해결 키 포인트
- 빙산이 두덩어리로 나눠졌는지 알아내야 하므로 BFS 사용
- 모든 빙산이 녹을 때까지 반복
+ 최고 높이 빙산까지 반복은 문제 발생- 날짜 증가
- 방문 기록 초기화
- BFS로 방문 기록하면서 덩어리 수 세기 : 방문하지 않은 빙산이 있을 경우 count 증가 및 BFS 실행
- count가 2 이상일 경우 종료
- 빙산에서 녹는 부분 계산
- 주변에 0이 있는만큼 minus 배열에 해당 부분을 감소
+ 바로 빙산을 녹이면 다른 빙산의 녹는 높이 계산 시 오류 발생
- 주변에 0이 있는만큼 minus 배열에 해당 부분을 감소
코드
import java.io.*;
import java.util.*;
public class Main {
public static int N, M;
public static int [][] lists;
public static boolean [][] visited;
public static int [] dx = {1,0,-1,0};
public static int [] dy = {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());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
// 빙산 입력
lists = new int [N][M];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
lists[i][j] = Integer.parseInt(st.nextToken());
}
}
boolean checkResult = false;
int result = 0;
boolean checkICE = true;
// 모든 빙산이 녹을 때까지 반복
while(checkICE) {
// 결과 증가
result++;
// 빙산 덩어리 개수
int count = 0;
// 방문 기록 초기화
visited = new boolean[N][M];
// 방문 안한 빙산 방문
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if(!visited[i][j] && lists[i][j] > 0) {
BFS(i, j);
count++;
}
}
}
// 빙산이 2덩어리 이상 나눠졌을 때 종료
if(count >= 2) {
checkResult = true;
break;
}
// 빙산에서 녹는 부분 계산
int [][] minus = new int [N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if(visited[i][j] && lists[i][j] > 0) {
for (int k = 0; k < 4; k++) {
int checkX = i + dx[k];
int checkY = j + dy[k];
if (checkRound(checkX, checkY) && lists[checkX][checkY] == 0) {
minus[i][j]--;
}
}
}
}
}
// 빙산 녹이기
checkICE = false; // 안녹을 경우, 모든 빙산이 녹은 것으로 반복 종료
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if(minus[i][j] < 0) {
checkICE = true;
lists[i][j] = Math.max(lists[i][j] + minus[i][j] , 0);
}
}
}
}
// 빙산이 2덩어리 이상 나눠졌을 경우 결과 출력
if(checkResult)
System.out.println(result-1);
// 아닐 경우 0 출력
else
System.out.println(0);
}
public static void BFS(int x, int y) {
Queue<Node> queue = new LinkedList<>();
queue.add(new Node(x,y));
visited[x][y] = true;
while(!queue.isEmpty()) {
Node value = queue.poll();
for (int i = 0; i < 4; i++) {
int newX = value.x + dx[i];
int newY = value.y + dy[i];
if(checkRound(newX, newY) && lists[newX][newY] > 0 && !visited[newX][newY]) {
visited[newX][newY] = true;
queue.add(new Node(newX, newY));
}
}
}
}
public static boolean checkRound(int newX, int newY) {
return (newX >= 0 && newY >= 0 && newX < N && newY < M);
}
public static class Node {
int x;
int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
}
반응형
'CodingTEST' 카테고리의 다른 글
[백준 18111] 마인크래프트 (JAVA) (2) | 2023.11.24 |
---|---|
[백준 14503] 로봇 청소기 (JAVA) (0) | 2023.11.23 |
[백준 2468] 안전 영역 (JAVA) (0) | 2023.11.23 |
[백준 5014] 스타트링크 (JAVA) (0) | 2023.11.21 |
[백준 1697] 숨바꼭질 (JAVA) (0) | 2023.11.21 |