백준/누적 합

15724 주지수

have a good time 2022. 5. 28. 14:17

1. 풀이

 

누적 합을 이용한다.

 

예제를 가지고 설명하겠다.

 

4 4
9 14 29 7
1 31 6 13
21 26 40 16
8 38 11 23
3
1 1 3 2
1 1 1 4
1 1 4 4

 

 

 

1) sum 배열

 

sum[i][j] = sum[i][j-1] + (i,j) 위치에 살고 있는 사람 수 

로 채운다. 

 

즉, 

 

9       23(9+14)       52(23+29)    59(52+7)

1       32(1+31)       38(32+6)      51(38+13)

 

이런 식으로 채운다.

 

<sum 배열>

 

 

sum 배열의 (1,1) 위치 값은 9 이다.

즉 sum[1][1] = 9

 

 

 

2) dp 배열

 

dp[i][j] = (1,1) 부터 (i,j) 까지의 인구수 합

 

=> dp[i][j] = dp[i-1][j] + sum[i][j]

 

 

즉,

 

<dp 배열>

 

 

3) 결과 출력

 

 

주어진 직사각형 범위의 (x1,y1) ~ (x2,y2) 의 사람 수 합은

 

dp[x2][y2] - dp[x2][y1-1] - dp[x1-1][y2] + dp[x1-1][y1-1] 로 구하면 된다.

 

즉, 문제 예제에 주어진

(1,1) ~ (3,2) 를 구할 때는

dp[3][2] - dp[3][0] - dp[0][2] + dp[0][0] 

 

=> dp[1][1] = 9 이고,

0행, 0열은 0으로 채워져 있다.

 

따라서 dp[3][2] = 102 이므로

102 - 0 - 0 + 0 = 102 가 답이 된다.

 

 

 

 

2. 최종 코드

 

 

 

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 sum[][] = 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++) {
				sum[i][j] = sum[i][j-1] +  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] + sum[i][j];
			}
		}
		
		int K = Integer.parseInt(br.readLine());
		
		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];
			System.out.println(result);
	  }
	}
}