[프로그래머스] 파괴되지 않은 건물 - JAVA

https://school.programmers.co.kr/learn/courses/30/lessons/92344

풀이

N X M 크기의 영역이 주어지고, 각 영역을 사각형 크기의 영역을 정해 일정 수를 더하고 빼주게 된다.

누적합을 이용하는 문제였다.

(a, b) 부터 (c, d) 까지의 사각형에 5씩 더해주기 위해서는

arr[a][b] += 5
arr[a+1][b+1] += 5
arr[a][b+1] -= 5
arr[a+1][b] -= 5

위처럼 더해주면 된다. 이렇게 수를 저장한 뒤 행마다 왼쪽에서 오른쪽으로 누적합해주고,

열마다 위에서 아래로 누적합해주면 된다.

[5, 0, 0, -5] [0, 0, 0, 0] [0, 0, 0, 0] [-5, 0, 0, 5]

이렇게 적은 뒤 누적합을 수행하면

[5, 5, 5, 0] [5, 5, 5, 0] [5, 5, 5, 0] [0, 0, 0, 0]

이렇게 원하는 영역에 누적합이 된 것을 확인할 수 있다.


메모리: 217MB

시간: 40.38ms

언어: Java 11

코드

class Solution {
    public int solution(int[][] board, int[][] skill) {
        int N = board.length;
        int M = board[0].length;

        int[][] sum = makeSumArr(skill, N, M);

        int answer = 0;
        for(int i = 0; i < N; i++) {
            for(int j = 0; j < M; j++) {
                if(board[i][j] + sum[i][j] > 0) {
                    answer++;
                }
            }
        }

        return answer;
    }

    private static int[][] makeSumArr(int[][] skill, int N, int M) {
        int[][] result = new int[N + 1][M + 1];

        for(int i = 0; i < skill.length; i++) {
            int type = skill[i][0];
            int degree = skill[i][5];
            if(type == 1) {
                degree *= -1;
            }

            result[skill[i][1]][skill[i][2]] += degree;
            result[skill[i][1]][skill[i][4] + 1] -= degree;
            result[skill[i][3] + 1][skill[i][2]] -= degree;
            result[skill[i][3] + 1][skill[i][4] + 1] += degree;
        }

        for(int i = 0; i < N + 1; i++) {
            for(int j = 1; j < M + 1; j++) {
                result[i][j] += result[i][j - 1];
            }
        }

        for(int j = 0; j < M + 1; j++) {
            for(int i = 1; i < N + 1; i++) {
                result[i][j] += result[i - 1][j];
            }
        }

        return result;
    }
}