본문으로 바로가기

[BaekJoon] 백준 - 미세먼지 안녕!

category 알고리즘/백준 2022. 5. 26. 17:41

 

 

공기청정기는 항상 1번 열에 설치되어 있고, 크기는 두 행을 차지한다. 공기청정기가 설치되어 있지 않은 칸에는 미세먼지가 있고, (r, c)에 있는 미세먼지의 양은 Ar,c이다.

1초 동안 아래 적힌 일이 순서대로 일어난다.

  1. 미세먼지가 확산된다. 확산은 미세먼지가 있는 모든 칸에서 동시에 일어난다.
    • (r, c)에 있는 미세먼지는 인접한 네 방향으로 확산된다.
    • 인접한 방향에 공기청정기가 있거나, 칸이 없으면 그 방향으로는 확산이 일어나지 않는다.
    • 확산되는 양은 Ar,c/5이고 소수점은 버린다.
    • (r, c)에 남은 미세먼지의 양은 Ar,c - (Ar,c/5)×(확산된 방향의 개수) 이다.
  2. 공기청정기가 작동한다.
    • 공기청정기에서는 바람이 나온다.
    • 위쪽 공기청정기의 바람은 반시계방향으로 순환하고, 아래쪽 공기청정기의 바람은 시계방향으로 순환한다.
    • 바람이 불면 미세먼지가 바람의 방향대로 모두 한 칸씩 이동한다.
    • 공기청정기에서 부는 바람은 미세먼지가 없는 바람이고, 공기청정기로 들어간 미세먼지는 모두 정화된다.

 

 

 

격자 위에 놓인 미세먼지를 확산시키고 공기청정기를 가동한 후에 격자 위에 남아있는 미세먼지를 구하는 문제.

 

문제에 나타난 단계를 잘 따라가면 된다. 

 

 

미세먼지 확산 Diffuse 함수

미세먼지는 동시에 확산되기 때문에 2차원 배열을 한개 더 생성하여 미세먼지의 확산만 고려하였고

원래 있던 배열에는 미세먼지가 확산되고 난 이후의 값을 저장했다. 

 

미세먼지 확산이 완료되면 두 배열의 값을 합쳐서 최종 상태가 된다. 

 

 

공기청정기 Cleaner 함수

공기청정기는 각 시계방향과 반시계 방향으로 총 2회 가동이 되며 바람은 격자의 끝에 다다랐을 때 변경된다. 

 

direction 배열 (d1, d2, d3, d4) 를 사용하여 시계방향(d1, d2)과 반시계방향(d3, d4)을 나누었고 

청소 단계는 처음 A 를 똑같이 복사한 배열을 생성해서 A의 값을 변경해주는 방식으로 했다. 

 

첫 시작점의 미세먼지는 항상 0이 되고, 방향에 따라 한칸씩 옮겨준다. 

다음 위치가 공기청정기가 있는 위치라면, 옮기지 않고 그대로 종료한다. 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    static int[][] A;
    static int R;
    static int C;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] tmp = br.readLine().split(" ");
        
        R = Integer.parseInt(tmp[0]);
        C = Integer.parseInt(tmp[1]);
        int T = Integer.parseInt(tmp[2]);
        A = new int[R][C];
        
        int cleaner = 0;
        int cleaner2 = 0;
        
        boolean flag = false;
        
        for(int i = 0; i<R; i++) {
            String[] input = br.readLine().split(" ");
            for(int j = 0; j<C; j++) {
                A[i][j] = Integer.parseInt(input[j]);
                
                if (A[i][j] == -1) {
                    if (!flag) {
                        cleaner = i; cleaner2 = i + 1;
                        flag = true;
                    }
                }
            }
        }
        int[] d1 = {0, -1, 0, 1};
        int[] d2 = {1, 0, -1, 0};
        
        int[] d3 = {0, 1, 0, -1};
        int[] d4 = {1, 0, -1, 0};
        
        int count = 0;
        while (count < T) {
            diffuse();
            clean(cleaner, d1, d2);
            clean(cleaner2, d3, d4);
            count ++;
            
        }
        
        int answer = 0;
        for(int i = 0; i<R; i++) {
            for(int j = 0; j<C; j++) {
                if (A[i][j] != -1)
                    answer += A[i][j];
            }
        }
        
        System.out.println(answer);
    }
    
    public static void diffuse() {
        int[][] new_A = new int[R][C];
        int[] d1 = { -1, 1, 0, 0};
        int[] d2 = { 0, 0, -1, 1};
        
        for(int i = 0; i<R; i++) {
            for(int j = 0; j<C; j++) {
                new_A[i][j] = 0;
            }
        }
        
        
        for(int i = 0; i<R; i++) {
            for(int j = 0; j<C; j++) {
                if ( A[i][j] > 0 ) {
                    int dust = A[i][j];
                    int count = 0;
                    
                    for(int k = 0; k<4; k++) {
                        if (i + d1[k] >= 0 && j + d2[k] >= 0 && i + d1[k] < R && j + d2[k] < C) {
                            if (A[i + d1[k]][j + d2[k]] != -1) {
                                new_A[i + d1[k]][j + d2[k]] += dust / 5;
                                count ++;
                            }
                        }
                    }
                    
                    A[i][j] = dust - ( (dust/5) * count );
                }
            }
        }
        
        for(int i = 0; i<R; i++) {
            for(int j = 0; j<C; j++) {
                A[i][j] += new_A[i][j];
            }
        }
    }
    
    public static void clean(int c_i, int[] d1, int[] d2) {
        int[][] tmp = deepCopy(A);
        int start_i = c_i;
        int start_j = 1;
        A[start_i][start_j] = 0;
        
        for(int i = 0; i<4; i++) {
            while(true) {
                int new_i = start_i + d1[i];
                int new_j = start_j + d2[i];
                
                if (!(new_i >= 0 && new_i < R && new_j >= 0 && new_j < C))
                    break;
                
                if (new_i == c_i && new_j == 0)
                    break;
                
                A[new_i][new_j] = tmp[start_i][start_j];
                start_i = new_i;
                start_j = new_j;
            }
        }
    }
    
    public static int[][] deepCopy(int[][] target) {
        int[][] result = new int[R][C];
        
        for(int i = 0; i<R; i++) {
            for(int j = 0; j<C; j++) {
                result[i][j] = target[i][j];
            }
        }
        
        return result;
    }
}

 

 

'알고리즘 > 백준' 카테고리의 다른 글

[BaekJoon] 백준 - 테트로미노  (0) 2022.05.30
[BaekJoon] 백준 - 뱀  (0) 2022.05.27
[BaekJoon] 백준 - 시험감독  (0) 2022.05.26
[BaekJoon] 백준 - 2048 (Easy)  (0) 2022.05.25
[BaekJoon] 백준 - 구슬 탈출2  (0) 2022.05.23