[2022 KAKAO BLIND RECRUITMENT] 파괴되지 않은 건물

최민길(Gale)·2023년 3월 28일
1

알고리즘

목록 보기
58/172

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/92344

이 문제는 누적합을 이용해서 풀 수 있습니다. 이 문제의 경우 단순 완전 탐색 방식으로 풀게 된다면 최대 1000X1000X250000 으로 시간 초과가 발생합니다. 따라서 이 문제는 반복문을 최소화하면서 문제를 풀 수 있는 방법을 사용해야 합니다.

이를 해결할 수 있는 방법이 누적합을 이용한 방법입니다. 매번 해당 범위를 탐색해서 값을 수정하는 대신 특정값만 값을 변경한 후 모든 값이 반영된 누적합 행렬을 계산한 후 이를 한번에 원본 행렬에 계산하는 방식으로 진행합니다. 이 때 (x1,y1)부터 (x2,y2)까지 n만큼의 변화는 (x1,y1)에 +n, (x1,y2+1)에 -n, (x2+1,y1)에 -n, (x2+1,y2+1)에 +n을 한 것과 같기 때문에 스킬의 개수만큼만 반복함으로 누적합 행렬을 계산할 수 있는 기저 행렬을 구할 수 있습니다. 이를 행 방향, 열 방향으로 이동시키며 누적합을 계산하고 이를 원본 행렬과 계산하면 문제를 풀 수 있습니다.

다음은 코드입니다.

import java.util.*;

class Solution {
    public int solution(int[][] board, int[][] skill) {
        int N = board.length;
        int M = board[0].length;
        
        int[][] tmp = new int[N+1][M+1];
        
        // 2차원 배열에서 (x1,y1)부터 (x2,y2)까지 n만큼의 변화는 (x1,y1)에 +n, (x1,y2+1)에 -n, (x2+1,y1)에 -n, (x2+1,y2+1)에 +n을 한 것과 같습니다.
        for(int i=0;i<skill.length;i++){
            int type = skill[i][0];
            int r1 = skill[i][1];
            int c1 = skill[i][2];
            int r2 = skill[i][3];
            int c2 = skill[i][4];
            int degree = skill[i][5];
            
            if(type==1) degree *= -1;
            
            tmp[r1][c1] += degree;
            tmp[r1][c2+1] -= degree;
            tmp[r2+1][c1] -= degree;
            tmp[r2+1][c2+1] += degree;
        }
        
        // 누적합을 이용해서 N*M 행렬을 한 번만 탐색 진행
        for(int i=0;i<=N;i++){
            // 가로 방향 누적합 계산
            for(int j=1;j<=M;j++){
                tmp[i][j] += tmp[i][j-1];
            }
        }
        for(int i=0;i<=M;i++){
            // 세로 방향 누적합 계산
            for(int j=1;j<=N;j++){
                tmp[j][i] += tmp[j-1][i];
            }
        }     
        
        int answer = 0;
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++){
                board[i][j] += tmp[i][j];
                if(board[i][j]>0) answer++;
            }
        }
        
        return answer;
    }
}

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글

관련 채용 정보