728x90
SMALL
백준 문제 풀이: 11660 [구간 합 구하기 5]
문제 링크: https://www.acmicpc.net/problem/11660
문제 설명:
2차원 배열에서 특정 구간의 합을 구하는 문제입니다. 입력된 행렬에서 여러 쿼리에 대해 지정된 좌표 범위의 합을 효율적으로 계산해야 합니다.
입력:
- 첫째 줄에 정수
n
과m
이 주어집니다. (1 ≤n
≤ 1,024, 1 ≤m
≤ 100,000) - 다음
n
개의 줄에는 행렬의 원소가 주어집니다. 행렬의 원소는 1,000 이하의 자연수입니다. - 이후
m
개의 줄에는 네 개의 정수x1
,y1
,x2
,y2
가 주어집니다.
출력:
- 각 쿼리에 대해 지정된 좌표 구간의 합을 한 줄에 하나씩 출력합니다.
문제 해결 코드
#include <iostream>
using namespace std;
int arr[1025][1025];
int prefixSum[1025][1025];
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int n, m;
cin >> n >> m;
// 입력받고 누적합 계산
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> arr[i][j];
prefixSum[i][j] = arr[i][j] + prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1];
}
}
// 쿼리 처리
for (int i = 0; i < m; i++) {
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
int sum = prefixSum[x2][y2]
- prefixSum[x1 - 1][y2]
- prefixSum[x2][y1 - 1]
+ prefixSum[x1 - 1][y1 - 1];
cout << sum << '\n';
}
return 0;
}
예제
입력:
4 3
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
2 2 3 4
3 4 3 4
1 1 4 4
출력:
27
6
64
코드 설명
- 누적합 계산:
prefixSum[i][j]
는 (1,1)부터 (i,j)까지의 합을 저장합니다.- 이를 통해 특정 구간의 합을 O(1)에 계산할 수 있습니다.
- 구간 합 계산:
- 주어진 좌표 범위에서 누적합을 사용해 결과를 구합니다:
prefixSum[x2][y2]
: 구간의 전체 합- prefixSum[x1-1][y2]
: 제외할 위쪽 영역- prefixSum[x2][y1-1]
: 제외할 왼쪽 영역+ prefixSum[x1-1][y1-1]
: 제외된 영역의 중복 보정
시간 복잡도
- 누적합 계산: O(n²)
- 각 쿼리 처리: O(1)
- 전체 시간 복잡도: O(n² + m)
결과
코드는 2차원 배열에서의 구간 합 문제를 효율적으로 해결하며, 누적합 기법을 통해 O(1)로 쿼리를 처리할 수 있습니다. 입력 크기가 최대 1024×1024이므로 문제의 제약을 만족하는 성능을 보장합니다.
다른 접근 방식이나 개선 사항이 있다면 댓글로 공유 부탁드립니다!
728x90
LIST
'BAEKJOON > 다이나믹 프로그래밍' 카테고리의 다른 글
백준 1890번 [점프](C++)-yes6686- 티스토리 (0) | 2024.12.29 |
---|---|
백준 12865번 [평범한 배낭](C++)-yes6686- 티스토리 (0) | 2024.12.29 |
백준 11054번 [가장 긴 바이토닉 부분 수열](C++)-yes6686- 티스토리 (1) | 2024.12.29 |
백준 9251번 [LCS](C++)-yes6686- 티스토리 (0) | 2024.12.29 |
백준 2096번 [내려가기](C++) -yes6686- 티스토리 (0) | 2024.12.26 |