https://www.acmicpc.net/problem/11660
11660번: 구간 합 구하기 5
첫째 줄에 표의 크기 N과 합을 구해야 하는 횟수 M이 주어진다. (1 ≤ N ≤ 1024, 1 ≤ M ≤ 100,000) 둘째 줄부터 N개의 줄에는 표에 채워져 있는 수가 1행부터 차례대로 주어진다. 다음 M개의 줄에는 네
www.acmicpc.net
- 문제
2차원 배열상의 표가 주어지면 (x1,y1)부터 (x2,y2)까지의 합을 구하는 문제다.
- 해설
구간 합 구하기 4까지는 일차원 배열 문제라 쉬웠는데, 이것도 이차원 배열이라는 거 빼고는 다를 게 없다.
가장 먼저 값을 어떻게 넣어줄건지를 생각해야 한다.
(가로로 먼저 더하고 세로로 더하는 방법을 사용했다.)
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
1. 이 있으면 먼저 가로로 더해서
1 3 6 10
2 5 9 14
3 7 12 18
4 9 15 22
2. 이렇게 만들고 세로로 더해서
1 3 6 10
3 8 15 24
6 15 27 42
10 24 42 64
이렇게 만들었다.
마지막으로
3. (4,4)에서 (4,4)까지의 합을 구하려고 하면
(4,4) - (4-1,4) - (4,4-1) + (4-1,4-1) == (4,4) - (3,4) - (4,3) + (3,3)을 하면 정답이 나온다.
64 - 42 - 42 + 27 = 7
비슷하게 (2,3)에서 (4,4)까지의 합을 구하려고 하면
(4,4) - (2-1,4) - (4,3-1) + (2-1,3-1) == (4,4) - (1,4) - (4,2) + (1,2)
64 - 10 - 9 + 3 = 48
이런 식으로 풀 수 있다.
- 풀이
#include <iostream>
#include <vector>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N, M, x1, y1, x2, y2, temp;
cin >> N >> M;
vector<int> vX(1025, 0);
vector<vector<int>> vBoard(1025, vX); // 이차원 배열에 저장해야 함
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
cin >> temp;
vBoard[i][j] = temp + vBoard[i][j - 1]; // 1. 가로로 증가함에 따라 더해준다( 1 2 3 4 ) 이렇게 있으면 ( 1 3 6 10) 이렇게 저장
}
}
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
vBoard[i][j] += vBoard[i - 1][j]; // 2. 세로로 증감하에 따라 더함(가로로는 이미 더했으니 그 위에 값과 현재 값만 저장하면 됨)
}
}
for (int i = 1; i <= M; i++)
{
cin >> x1 >> y1 >> x2 >> y2;
cout << vBoard[x2][y2] - vBoard[x2][y1 - 1] - vBoard[x1 - 1][y2] + vBoard[x1 - 1][y1 - 1] << '\n'; // 3. 현재 - 좌측 값 - 위에 값 + 좌상값 = 정답
}
return 0;
}
- 새롭게 알게 된 점
'Algorithm > Baekjoon BOJ' 카테고리의 다른 글
[백준][C++] 10986: 나머지 합 (0) | 2022.11.14 |
---|---|
[백준][C++] 25682: 체스판 다시 칠하기 2 (0) | 2022.11.12 |
[백준][C++] 16139: 인간-컴퓨터 상호작용 (0) | 2022.11.11 |
[백준][C++] 2559: 수열 (0) | 2022.11.10 |
[백준][C++] 11659: 구간 합 구하기 4 (0) | 2022.11.10 |