2 분 소요

문제

문제 바로가기

입력

첫째 줄에 R, C, T (6 ≤ R, C ≤ 50, 1 ≤ T ≤ 1,000) 가 주어진다.

둘째 줄부터 R개의 줄에 Ar,c (-1 ≤ Ar,c ≤ 1,000)가 주어진다. 공기청정기가 설치된 곳은 Ar,c가 -1이고, 나머지 값은 미세먼지의 양이다. -1은 2번 위아래로 붙어져 있고, 가장 윗 행, 아랫 행과 두 칸이상 떨어져 있다.

출력

첫째 줄에 T초가 지난 후 구사과 방에 남아있는 미세먼지의 양을 출력한다.


접근방법

문제에 적힌 조건을 보고 순서대로 해결해나가면 쉽게 풀 수 있는 문제였다.

  • 먼지가 확산하는 방향을 dx, dy 로 설정하고, 공기청정기가 위치한 좌표를 찾아서 cleanUp, cleanDown으로 저장했다.
  • 미세먼지의 확산이 모든 칸에서 동시에 일어나므로 spread()에서 확산 전의 map을 복사하고, 복사한 임시배열에 변경된 값을 대입해서 최종적으로 다시 map으로 반환해주었다.

img

  • cleaner()에서 다음 그림과 같은 방향 그대로 순서대로 값을 한 칸씩 이동해주고, 바람이 나오는 방향 바로 옆에 있는 칸은 0으로 만들어주면 된다.

풀이

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

public class Main {
    static int R, C, T;
    static int[][] map;
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};
    static int cleanUp, cleanDown;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        T = Integer.parseInt(st.nextToken());
        map = new int[R][C];

        for(int i = 0; i < R; i++) {
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < C; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        for(int i = 0; i < R; i++) {
            if(map[i][0] == -1) {
                cleanUp = i;
                cleanDown = i+1;
                break;
            }
        }

        while(T-- > 0) {
            map = spread();
            cleaner();
        }

        int sum = 0;
        for(int i = 0; i < R; i++) {
            for(int j = 0; j < C; j++) {
                sum += map[i][j];
            }
        }

        System.out.println(sum+2);
    }

    public static int[][] spread() {
        int[][] t_map = new int[R][C];
        for(int i = 0; i < R; i++) {
            for(int j = 0; j < C; j++) {
                t_map[i][j] = map[i][j];
            }
        }
        for(int i = 0; i < R; i++) {
            for(int j = 0; j < C; j++) {
                if(map[i][j] == -1)
                    continue;
                for(int k = 0; k < 4; k++) {
                    int tr = i + dx[k];
                    int tc = j + dy[k];
                    if(tr >= 0 && tc >= 0 && tr < R && tc < C) {
                        if(map[tr][tc] != -1) {
                            t_map[tr][tc] += map[i][j] / 5;
                            t_map[i][j] -= map[i][j] / 5;
                        }
                    }
                }
            }
        }
        return t_map;
    }

    public static void cleaner() {
        for(int i = cleanUp-1; i > 0; i--) {
            map[i][0] = map[i-1][0];
        }
        for(int i = 0; i < C-1; i++) {
            map[0][i] = map[0][i+1];
        }
        for(int i = 0; i < cleanUp; i++) {
            map[i][C-1] = map[i+1][C-1];
        }
        for(int i = C-1; i > 1; i--) {
            map[cleanUp][i] = map[cleanUp][i-1];
        }
        map[cleanUp][1] = 0;

        for(int i = cleanDown+1; i < R-1; i++) {
            map[i][0] = map[i+1][0];
        }
        for(int i = 0; i < C-1; i++) {
            map[R-1][i] = map[R-1][i+1];
        }
        for(int i = R-1; i > cleanDown; i--) {
            map[i][C-1] = map[i-1][C-1];
        }
        for(int i = C-1; i > 1; i--) {
            map[cleanDown][i] = map[cleanDown][i-1];
        }
        map[cleanDown][1] = 0;
    }
}

댓글남기기