baekjoon
백준 11660 구간 합 구하기 5
nownow
2024. 11. 3. 08:58
https://www.acmicpc.net/problem/11660
표는 2^10까지 커지고 결과를 10만번까지 구해야 할 수도 있다.
합계를 구하기 위해 제시된 공간을 매번 2중 for문으로 훑어 합을 구하게 되면
최악의 상황에는 1024 * 100000 번 연산을 해야한다. 1억번이 넘는 연산이기에 1초 시간제한을 맞추기 어렵다.
효율적으로 계산하기위해 메모이제이션을 도입한다.
처음에는 위와 같은 표가 있으면 더한 값을 계속 누적해나가며 이전 행의 누적값에 이어서 누적하여
위 예시와 같은 상황에서
1 3 6 10
12 15 19 24
....
과 같은 형식으로 구현하려 했다. 하지만 이런식으로 구현한다면 2행2열에서부터 3행3열까지 합한다고 할 때
3행 3열의 누적값에서 시작지점의 한칸 전 누적합을 빼고 시작행부터 끝 행까지 돌며 필요없는 값들을 빼주어야 한다.
ex)2행 4열과 3행 1열의 값.
필요이상의 연산이 들어가고 구현도 복잡해진다고 판단해서 방식을 바꾸었다.
총 누적값을 구하는 것이 아니라 각 행의 누적값을 구하도록 바꾼다. 예시입력에서는
1 3 6 10
2 5 9 14
....
과 같은 형식으로 저장된다. 이러면 시작행부터 끝 행까지 돌며
끝열의 누적값 - 시작열-1열의 누적값을 더해주면 된다.
구현의 편의를 위해 배열의 크기를 조금 키워 인덱스를 0이아닌 1부터 시작하게 하여
시작열이 첫 열일때도 시작열-1의 상황에서 따로 예외처리를 하지 않도록 해주었다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
import java.util.*;
public class Main {
static int n,count;
static int[][] arr = new int[1100][1100];
static int[][] dp = new int[1100][1100];
static int startrow,startcol,endrow,endcol;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String str = br.readLine();
StringTokenizer token = new StringTokenizer(str);
n = Integer.parseInt(token.nextToken());
count= Integer.parseInt(token.nextToken());
for(int i=1;i<=n;i++){
str = br.readLine();
token = new StringTokenizer(str);
for(int j=1;j<=n;j++){
arr[i][j]=Integer.parseInt(token.nextToken());
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dp[i][j]=dp[i][j-1]+arr[i][j];
}
}
for(int i=0;i<count;i++)
{
int result=0;
str = br.readLine();
token = new StringTokenizer(str);
startrow=Integer.parseInt(token.nextToken());
startcol=Integer.parseInt(token.nextToken());
endrow=Integer.parseInt(token.nextToken());
endcol=Integer.parseInt(token.nextToken());
for(int j=startrow;j<=endrow;j++){
result+=dp[j][endcol];
result-=dp[j][startcol-1];
}
bw.write(result+"\n");
}
bw.flush();
bw.close();
}
}