본문 바로가기

코딩 테스트 문제 풀이/백준

백준 - 구간 합 구하기 4 (11659)


[Silver III] 구간 합 구하기 4 - 11659

성능 요약

메모리: 55544 KB, 시간: 548 ms

분류

누적 합

제출 일자

2024년 8월 22일 13:19:58

문제 설명

수 N개가 주어졌을 때, i번째 수부터 j번째 수까지 합을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 수의 개수 N과 합을 구해야 하는 횟수 M이 주어진다. 둘째 줄에는 N개의 수가 주어진다. 수는 1,000보다 작거나 같은 자연수이다. 셋째 줄부터 M개의 줄에는 합을 구해야 하는 구간 i와 j가 주어진다.

출력

총 M개의 줄에 입력으로 주어진 i번째 수부터 j번째 수까지 합을 출력한다.


알고리즘을 모른채로 풀었을 때, 시간 복잡도 때문에 오답처리되었던 문제이다. 

 

합 배열을 생성해서 시간 복잡도를 O(N) 에서 O(1) 로 줄여야한다.

 

합배열 예시

반복문을 통해 기존 배열을 가공한 합배열을 생성하고 사용하면 된다.

 

2번째 줄로 주어진 배열을 합배열로 변환하고, 합배열 내 요소들의 구간합을 구하면 된다.

 

구간합 공식

S[j] - S[i-1]

 

 

i ~ j 까지의 구간합을 구하는 것이니,

 

S[j] = j 구간까지의 전체 구간합

S[i-1] = 시작 인덱스 이전 구간합

 

위의 값을 빼주면 i ~ j 까지의 구간합을 구할 수 있다.

 

 

답안

import java.io.*;
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());

        StringBuffer sb = new StringBuffer();

        int numCnt = Integer.parseInt(st.nextToken());
        int sizeCnt = Integer.parseInt(st.nextToken());

        StringTokenizer num = new StringTokenizer(br.readLine());

        int[] sumArr = new int[numCnt + 1];

        sumArr[0] = 0;

        for(int i = 1; i < numCnt + 1; i++){
            sumArr[i] = sumArr[i - 1] + Integer.parseInt(num.nextToken());
        }

        for(int i = 1; i <= sizeCnt; i++){
            StringTokenizer st2 = new StringTokenizer(br.readLine());

            int from = Integer.parseInt(st2.nextToken());
            int to = Integer.parseInt(st2.nextToken());
            sb.append(sumArr[to] - sumArr[from -1]).append("\n");
        }

        System.out.println(sb);

        br.close();
    }
}

 

 

 

후기

 

모르는 문제를 마주했을 때 어느 정도의 시간 제한은 필요한 것 같다. 한 문제에 너무 많은 시간을 소요했고, 체력적으로도 지치는 걸 느꼈다. 그리고, 내가 어떤 의도로 이 코드를 작성했는지 알 수 있도록 주석을 자세히 달아두어야할 것 같다. 책을 보고 내 코드를 보면 왜 이렇게 짰는지 기억이 잘 나질 않는다..