아이디어
(x1, y1) ~ (x2, y2) 까지의 직사각형에 존재하는 값들의 합을 구하기 위해 먼저 (1, 1) 에서 (x, y) 까지의 합을 담고 있는 dp 배열을 만든다.
dp[i][j] 를 (1, 1) 에서 (i, j) 까지 만들어지는 직사각형에 존재하는 값들의 합이라고 정의한다면
(x1, y1) ~ (x2, y2) 직사각형에 존재하는 값들의 합은
dp[x2][y2] - dp[x2][y1 - 1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1]
이 된다.
(1, 1) 에서 (i, j) 까지 직사각형에 존재하는 값들의 합인 dp[i][j] 에 대한 점화식은 다음과 같이 세울 수 있다.
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + 영토[i][j]
풀이코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[][] populations = new int[N + 1][M + 1];
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= M; j++) {
populations[i][j] = Integer.parseInt(st.nextToken());
}
}
int[][] dp = new int[N + 1][M + 1];
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + populations[i][j];
}
}
int K = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
int x1 = Integer.parseInt(st.nextToken());
int y1 = Integer.parseInt(st.nextToken());
int x2 = Integer.parseInt(st.nextToken());
int y2 = Integer.parseInt(st.nextToken());
int result = dp[x2][y2] - dp[x2][y1 - 1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1];
sb.append(result).append("\n");
}
System.out.println(sb);
}
}
'Algorithm > 백준 알고리즘' 카테고리의 다른 글
16234번. 인구 이동 (1) | 2023.10.08 |
---|---|
18808번. 스티커 붙이기 (1) | 2023.10.08 |
2294번. 동전 2 (0) | 2023.10.06 |
2239번. 동전 1 (0) | 2023.10.06 |
2138번. 전구와 스위치 (0) | 2023.10.03 |