[boj] (s5) 2167 2차원 배열의 합

강신현·2023년 1월 3일
0

문제

https://www.acmicpc.net/problem/2167


2차원 배열의 최대 크기는 300*300

(i, j) 위치부터 (x, y) 위치까지에 저장되어 있는 수들의 합을 k번 구한다. 최대 10,000번

따라서 최악의 경우 300x300x10,000 번 연산을 해야함 -> 시간초과가 될 수도 있음

-> 누적합 이용
-> 시작점을 (1,1)로 두고 이차배열의 특정 위치를 입력 받을 때 시작점에서 특정 위치까지의 합을 구해 저장하도록 하자.
-> 하지만 이방법은 나중에 (i, j) 위치부터 (x, y) 위치까지의 구간합을 구할 때 중복되는 구간을 생각해야 하기 때문에 좀 복잡하다고 판단함
-> 가로 방향으로의 구간합만 구해서 저장해놓고 (i, j) 위치부터 (x, y) 위치까지의 합을 가로방향으로 쪼개서 따로 구한다음 합치는 방법으로 구현


풀이

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int N, M, K;
int arr[301][301];
int s[301][301]; // 시작점을 (1,1)에서 특정 위치까지의 합

int Sum(int i, int j, int x, int y){
    int sum=0;
    for(int t=i;t<=x;t++){
        sum += s[t-1][y-1];
        if(j-2>=0) sum -= s[t-1][j-2];
    }

    return sum;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin >> N >> M;

    for(int i=0;i<N;i++){
        for(int j=0;j<M;j++){
            cin >> arr[i][j];

            if(i==0 && j==0){
                s[0][0] = arr[0][0];
            }
            else{
                if(j-1 >= 0) s[i][j] += s[i][j-1];
                s[i][j] += arr[i][j];
            }
        }
    }

    cin >> K;
    for(int t=0;t<K;t++){
        int i,j,x,y;
        cin >> i >> j >> x >> y;

        cout << Sum(i,j,x,y) << "\n";
    }

}

다른 풀이

https://ongveloper.tistory.com/277
이런식으로 하려다가 중복 되는 부분을 빼주는 규칙을 찾기 어려워서 위와 같이 풀었는데
종이에 그려가며 규칙을 찾아보는 노력이 필요할듯 (머리속으로만 하다가 못찾음ㅎ..)

profile
땅콩의 모험 (server)

0개의 댓글