mang_dev
맹꽁거리는 개발자
mang_dev
전체 방문자
오늘
어제
  • 분류 전체보기 (185)
    • Frontend (2)
      • Next.js (1)
    • Backend (3)
      • GraphQL (2)
    • Book (1)
      • 기타 (1)
    • Old (177)
      • 알고리즘 퍼즐 (1)
      • 백준 (131)
      • 프로그래머스 (0)
      • Codility (15)
      • LeetCode (7)
      • Codewars (1)
      • Codeforces (0)
      • Django (6)
      • React (2)
      • Naver Map Api (3)
      • Web UI (4)
      • Introduction to Cloud (2)
hELLO · Designed By 정상우.
mang_dev

맹꽁거리는 개발자

백준 2167번 2차원 배열의 합 // C++
Old/백준

백준 2167번 2차원 배열의 합 // C++

2020. 3. 10. 21:58

문제

 

2차원 배열이 주어졌을 때 (i, j) 위치부터 (x, y) 위치까지에 저장되어 있는 수들의 합을 구하는 프로그램을 작성하시오. 배열의 (i, j) 위치는 i행 j열을 나타낸다.

입력

첫째 줄에 배열의 크기 N, M(1 ≤ N, M ≤ 300)이 주어진다. 다음 N개의 줄에는 M개의 정수로 배열이 주어진다. 배열에 포함되어 있는 수는 절댓값이 10,000보다 작거나 같은 정수이다. 그 다음 줄에는 합을 구할 부분의 개수 K(1 ≤ K ≤ 10,000)가 주어진다. 다음 K개의 줄에는 네 개의 정수로 i, j, x, y가 주어진다(i ≤ x, j ≤ y).

출력

K개의 줄에 순서대로 배열의 합을 출력한다. 배열의 합은 32bit-int 범위를 초과하지 않는다.

 


 

풀이

 

합을 구하는 경우의 수가 최대 10,000개이기 때문에 for문을 사용해서 그때 그때 합을 구하면 시간이 오래걸리게 된다.

 

따라서 DP 방식을 사용하여 배열의 합을 구해야 한다.

 

먼저, (1,1)에서 (X,Y)까지의 총합을 담고 있는 배열을 하나 선언한다.

 

sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + arr[i][j]

 

(X,Y)까지의 총합은 위의 그림에서 "초록 + 파랑 - 노랑 + (X,Y)의 값"으로 구할 수 있다.

 

 

이렇게 (1,1)에서부터 각 좌표까지의 총합을 구했다면, (A,B)에서 (C,D)까지의 총합 역시 구할 수 있다.

 

 

 

 

(A,B)에서 (C,D)의 합은, sum(C,D) - sum(A-1,B) - sum(A,B-1) + sum(A-1,B-1)로 구할 수 있다.

 

마지막에 sum(A-1,B-1)을 더해주는 이유는 위 그림에서 초록 부분이 뺄셈에서 두번 빠지기 때문이다.


 

코드

더보기
#include <iostream>

using namespace std;

int N, M;
int arr[301][301];
int sum[301][301] = { 0, };

void calc();
void solve();

int main() {
	cin >> N >> M;

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

	calc();

	solve();

	return 0;
}

void calc() {
	sum[1][1] = arr[1][1];

	for (int i = 2; i <= N; i++) {
		sum[i][1] = sum[i - 1][1] + arr[i][1];
	}

	for (int i = 2; i <= M; i++) {
		sum[1][i] = sum[1][i-1] + arr[1][i];
	}

	for (int i = 2; i <= N; i++) {
		for (int j = 2; j <= M; j++) {
			sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + arr[i][j];
		}
	}

}

void solve() {
	int K;

	cin >> K;

	for (int i = 0; i < K; i++) {
		int x1, x2, y1, y2;
		cin >> y1 >> x1 >> y2 >> x2;

		cout << sum[y2][x2] - sum[y1 - 1][x2] - sum[y2][x1 - 1] + sum[y1 - 1][x1 - 1] << "\n";
	}
}
저작자표시 (새창열림)

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

백준 12100번 2048 // C++  (0) 2020.03.11
백준 14501번 퇴사 // C++  (0) 2020.03.11
백준 1182번 부분수열의 합 // C++  (0) 2020.03.05
백준 10974번 모든 순열 // C++  (0) 2020.03.05
백준 10973번 이전 순열 // C++  (0) 2020.03.05
    'Old/백준' 카테고리의 다른 글
    • 백준 12100번 2048 // C++
    • 백준 14501번 퇴사 // C++
    • 백준 1182번 부분수열의 합 // C++
    • 백준 10974번 모든 순열 // C++
    mang_dev
    mang_dev

    티스토리툴바