카테고리 없음
백준 알고리즘 11660번
ELpsy
2023. 12. 8. 15:14
https://www.acmicpc.net/problem/11660
11660번: 구간 합 구하기 5
첫째 줄에 표의 크기 N과 합을 구해야 하는 횟수 M이 주어진다. (1 ≤ N ≤ 1024, 1 ≤ M ≤ 100,000) 둘째 줄부터 N개의 줄에는 표에 채워져 있는 수가 1행부터 차례대로 주어진다. 다음 M개의 줄에는 네
www.acmicpc.net
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine());
int dataN = Integer.parseInt(stringTokenizer.nextToken()); // 배열크기
int quizN = Integer.parseInt(stringTokenizer.nextToken()); // 질의개수
long[][] dataArray = new long[dataN + 1][dataN + 1]; // 원본 배열
long[][] prefixSum = new long[dataN + 1][dataN + 1]; // 구간 합 배열
for (int i = 1; i < dataArray.length; i++) { // 원본 배열 생성
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
for (int j = 1; j < dataArray[i].length; j++) {
dataArray[i][j] = Long.parseLong(stringTokenizer.nextToken());
}
}
for (int i = 1; i < prefixSum.length; i++) { // 구간 합 배열 생성
for (int j = 1; j < prefixSum[i].length; j++) {
prefixSum[i][j] = prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1]+dataArray[i][j];
}
}
for (long[] temp : dataArray) {
for (long temp1 : temp)
System.out.print(temp1 + " ");
System.out.println();
}
for (int i = 0; i < quizN; i++) { //질의 받고 결과 출력
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
int x1 = Integer.parseInt(stringTokenizer.nextToken());
int y1 = Integer.parseInt(stringTokenizer.nextToken());
int x2 = Integer.parseInt(stringTokenizer.nextToken());
int y2 = Integer.parseInt(stringTokenizer.nextToken());
long result = prefixSum[x2][y2] - prefixSum[x2][y1 - 1] - prefixSum[x1 - 1][y2] + prefixSum[x1 - 1][y1 - 1];
System.out.println(result);
}
}
}
1. 구간 합 VS 부분 합
- Prefix sum(구간 합) : 구간 합이란 수들의 나열에서 특정 구간의 합을 의미한다. 구간 합 알고리즘은 보통 1차원배열에서 i~k 인덱스 사이의 값들의 합을 구하는데 사용한다.
- Partial sum(부분 합) : 부분 합이란 구간 합과 달리 처음부터 특정인덱스까지의 합을 의미한다. 즉 0~k 인덱스 사이의 값들의 합을 의미한다.
2. 구간 합 알고리즘
- 반복문을 사용하여 i~k사이의 값을 더하는 알고리즘의 시간복잡도는 O(n)이다.
- 이 같은 알고리즘을 사용할 경우 n의 값이 클 경우 이를 정해진 시간 내에 해결할 수 없다.
- 하지만 구간 합 알고리즘을 사용하여 구간합을 구하는 경우 O(1)의 성능을 갖는다.
- 구간 합 알고리즘은 현재 진행단계까지의 인덱스까지 값의 합을 저장하는 sum[]배열을 사용한다.
- j번째 바로 앞까지의 총합에 arr[j] 값을 더하면 j번째까지의 총합을 의미하므로 sum[j] = sum[j-1] + arr[j] 로 표현할 수 있다.