카테고리 없음
백준 [자바 java] 2573 : 빙산
잔디🌿
2024. 11. 15. 18:48
정말정말정말 오랜만에 알고리즘 문제를 풀었다.
감이 많이 줄어든 것 같다. 앞으로 좀 가끔이라도 풀어야겠다.
문제
https://www.acmicpc.net/problem/2573
해설
이 문제는 크게 두가지 문제가 있다.
- 1년뒤 빙하의 배열을 만들기
- 빙하의 덩어리 수를 체크하기
빙하 덩어리 확인하기
static class xy{
int x;
int y;
xy(int x,int y){
this.x = x;
this.y = y;
}
}
우선 x,y 좌표를 스택에 저장하기 위해서 클래스를 하나 만들었다.
int[] dx = {0,1,0,-1};
int[] dy = {1,0,-1,0};
또한 dx, dy 테크닉을 사용하기 위해서 위와 같은 배열을 만들었다.
Stack<xy> stack = new Stack<>();
int[][] vis = new int[n][m];
int fin = 0;
for(int i = 0;i<n;i++){
for(int j = 0;j<m;j++){
if(arr[i][j] !=0 && vis[i][j] == 0){
if(fin == 1){
System.out.println(answer);
System.exit(0);
}
stack.push(new xy(i,j));
while(!stack.isEmpty()){
//System.out.println(8);
xy xy = stack.pop();
if(vis[xy.x][xy.y] == 1) continue;
vis[xy.x][xy.y] = 1;
//System.out.println(arr[xy.x][xy.y]);
for(int k =0;k<4;k++){
//0 갯수 구하기
int xx = xy.x + dx[k];
int yy = xy.y + dy[k];
if(xx >= 0 && xx <n && yy >= 0 && yy < m){
if(arr[xx][yy] != 0 && vis[xx][yy] == 0){
stack.push(new xy(xx,yy));
}
}
}
}
fin =1;
}
}
}
이 부분이 빙하의 덩어리를 확인하는 부분이다. dfs를 통해서 파악하였다. 여기서는 덩어리의 갯수가 중요한 것이 아니라 덩어리가 두개 이상이냐가 중요하으로, 만약 덩어리 하나를 탐색했는데 또 다른 덩어리가 나오면 바로 끝내기로 했다.
오랜만에 하니까 vis 부분을 업데이트 하는 코드의 위치를 헷갈렸었다. 주의해야겠다.
빙산 깎기
int[][] arr2 = new int[n][m];
//빙산 깎아냄
for(int i = 0;i<n;i++){
for(int j = 0;j<m;j++){
int zero = 0;
if(arr[i][j] == 0) continue;
for(int k =0;k<4;k++){
//0 갯수 구하기
int xx = i + dx[k];
int yy = j + dy[k];
if(xx >= 0 && xx <n && yy >= 0 && yy < m){
if(arr[xx][yy] == 0){
zero++;
}
}
}
if(zero != 0){
if(arr[i][j] - zero <= 0){
arr2[i][j] = 0;
}
else{
arr2[i][j] = arr[i][j] - zero;
}
change++;
}
else{
arr2[i][j] = arr[i][j];
}
}
}
arr = arr2.clone();
if(change == 0){
System.out.println(0);
System.exit(0);
}
answer++;
}
위 코드에서는 빙하를 깎는다. 0이 아닌 좌표의 상하좌우를 탐색하여, 0인 좌표의 갯수를 구하고 배열을 업데이트 한다.
이 때 처음 입력받았던 arr에 바로 업데이트를 하면 오류가 발생한다. 꼭 다른 배열에 업데이트를 먼저 하고 옮겨야한다.