강잇
강이의 개발블로그
강잇
전체 방문자
오늘
어제
  • 분류 전체보기 (102)
    • Langauge (32)
      • Java-basic (29)
      • Java (3)
    • SpringBoot (7)
    • Algorithm (5)
      • BAEKJOON (5)
    • WEB (7)
      • HTML & CSS (7)
    • DB (1)
      • MySQL (1)
    • OS (17)
      • Mac (2)
      • Linux (4)
      • Terminal Command (11)
    • Computer Science (7)
      • Hard ware (1)
      • Database (1)
      • Data structure (2)
      • Algorithm (2)
      • Network (1)
    • Git (5)
      • 개념 (1)
      • 활용 (1)
      • Trouble Shooting (2)
    • ETC. (13)
      • Install (6)
      • IntelliJ (1)
      • Eclipse (2)
      • Error (3)
      • Tip (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 알고리즘 공부
  • 백준
  • 메소드
  • CSS 박스 크기 설정
  • 자바
  • 메서드
  • til
  • CSS 속성

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
강잇

강이의 개발블로그

[백준] 11659 구간 합 구하기 4 - Java
Algorithm/BAEKJOON

[백준] 11659 구간 합 구하기 4 - Java

2022. 6. 24. 05:16

문제

https://www.acmicpc.net/problem/11659

 

11659번: 구간 합 구하기 4

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

www.acmicpc.net

시간제한 : 1초 (100,000,000)

요구 : 수 N개가 주어졌을 때, i번째 수부터 j번째 수까지 합

수의 개수(N) : 100,000

합을 구해야 하는 횟수(M) : 100,000

질의마다 문제를 풀었을 때 시간제한에 걸리기 때문에 배열의 누적 합을 이용해 미리 배열을 만들어 놓고 구간합을 구하는 방향으로 잡았다.

문제 풀이

수의 개수(N) : 5
합을 구해야 하는 횟수(M) : 1
합을 구해야 하는 구간(i, j) : 2, 4

(1) 첫 번째 요소부터 구간의 최대 지점 j까지의 총합을 구한다.

(2) 첫 번째 요소부터 구간의 최소 지점인 i - 1까지의 합을 (1)에서 구한 합에서 뺀다.

 

아래의 그림은 누적합을 이용하여 각 인덱스의 배열에 적용시킨 그림이다.

누적합을 구하는 공식은 다음과 같다.

# 1차원 배열의 누적 합 구하는 공식
sumArr[i] = arr[i] + sumArr[i - 1]

이제 누적합을 적용시킨 배열을 처음 설명한 풀이 방법과 비교해보자.

처음 설명한 문제 풀이 방법은 다음과 같다.

(첫 번째 요소부터 인덱스 j까지의 합) - (첫 번째 요소부터 인덱스 i까지의 합)

위의 그림과 비교해보면 (첫 번째 요소부터 인덱스 j까지의 합)은 파란색으로 칠한 10에 해당되고, (첫 번째 요소부터 인덱스 i까지의 합)은 빨간색으로 칠한 1에 해당한다.

 

그럼 다음과 같이 공식을 정의할 수 있다.

# 1차원 배열의 구간 합 구하는 공식
result = sumArr[j] - sumArr[i - 1]

코드 1. 위의 풀이 방식을 그대로 구현

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[] arr = new int[n + 1];
        int[] sumArr = new int[n + 1];

        st = new StringTokenizer(br.readLine());
        // n개의 수를 입력받아 배열(arr)에 담는다.
        for (int i = 1; i <= n; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        // 배열(arr)을 이용해 누적합 배열을 구한다.
        for (int j = 1; j <= n; j++) {
            sumArr[j] = arr[j] + sumArr[j - 1];
        }
        // 누적합을 이용해 구간합을 출력한다.
        for (int k = 0; k < m; k++) {
            st = new StringTokenizer(br.readLine());
            int i = Integer.parseInt(st.nextToken());
            int j = Integer.parseInt(st.nextToken());

            System.out.println(sumArr[j] - sumArr[i - 1]);
        }
        br.close();
    }
}

코드 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[] sumArr = new int[n + 1];

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

        // 바로 누적합 배열을 생성
        for (int i = 1; i <= n; i++) {
            sumArr[i] = sumArr[i - 1] + Integer.parseInt(st.nextToken());
        }
        // 구간 합 출력
        for (int i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            int j = Integer.parseInt(st.nextToken());
            int k = Integer.parseInt(st.nextToken());

            System.out.println(sumArr[k] - sumArr[j - 1]);
        }
        br.close();
    }
}

저작자표시 (새창열림)

'Algorithm > BAEKJOON' 카테고리의 다른 글

[백준] 10828번 : 스택 [Java - 자바]  (0) 2022.07.25
[백준] 3273 두 수의 합 - Java  (0) 2022.07.02
[백준] 2559 수열  (0) 2022.06.25
[백준] 11660 구간 합 구하기 5 - Java  (0) 2022.06.23
    'Algorithm/BAEKJOON' 카테고리의 다른 글
    • [백준] 10828번 : 스택 [Java - 자바]
    • [백준] 3273 두 수의 합 - Java
    • [백준] 2559 수열
    • [백준] 11660 구간 합 구하기 5 - Java
    강잇
    강잇
    학습한 내용을 정리 및 기록하는 블로그

    티스토리툴바