Dev2yup의 프로그래밍 이야기 🖥 💻

C++

[105]C++(Cpp) 백준 2559번: 수열 문제 (누적 합)

엽동이 2023. 1. 11. 18:21

문제

매일 아침 9시에 학교에서 측정한 온도가 어떤 정수의 수열로 주어졌을 때, 연속적인 며칠 동안의 온도의 합이 가장 큰 값을 알아보고자 한다.

예를 들어, 아래와 같이 10일 간의 온도가 주어졌을 때, 

3 -2 -4 -9 0 3 7 13 8 -3

모든 연속적인 이틀간의 온도의 합은 아래와 같다.

이때, 온도의 합이 가장 큰 값은 21이다. 

또 다른 예로 위와 같은 온도가 주어졌을 때, 모든 연속적인 5일 간의 온도의 합은 아래와 같으며, 

이때, 온도의 합이 가장 큰 값은 31이다.

매일 측정한 온도가 정수의 수열로 주어졌을 때, 연속적인 며칠 동안의 온도의 합이 가장 큰 값을 계산하는 프로그램을 작성하시오. 

입력

첫째 줄에는 두 개의 정수 N과 K가 한 개의 공백을 사이에 두고 순서대로 주어진다. 첫 번째 정수 N은 온도를 측정한 전체 날짜의 수이다. N은 2 이상 100,000 이하이다. 두 번째 정수 K는 합을 구하기 위한 연속적인 날짜의 수이다. K는 1과 N 사이의 정수이다. 둘째 줄에는 매일 측정한 온도를 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -100 이상 100 이하이다. 

출력

첫째 줄에는 입력되는 온도의 수열에서 연속적인 K일의 온도의 합이 최대가 되는 값을 출력한다.

예제 입력 1 

10 2
3 -2 -4 -9 0 3 7 13 8 -3

예제 출력 1 

21

예제 입력 2 

10 5
3 -2 -4 -9 0 3 7 13 8 -3

예제 출력 2 

31

 

 

 

 

<풀이>

이 문제도 누적 합 알고리즘을 사용하는 문제이다.

https://dev2yup.tistory.com/114 <- 누적 합 알고리즘에 관한 설명

 

이 문제에서 핵심은 K일 동안의 가능한 연속 합을 모두 구해서 최대값을 출력하는 것이다.

 

1. 각 인덱스에 맞는 누적합을 저장한다.

 

2. 누적합을 이용해 K일 동안이므로 K일부터 N일 까지 모든 가능한 연속합을 구해 최대값을 저장한다.

for (int i = K; i <= N; i++){ // 모든 연속된 K일의 합들 중 최대인 합을 구한다.
        if (max_sum < (arr[i] - arr[i-K])) max_sum = arr[i] - arr[i-K];
    }

누적합 구하는 법 (i인덱스 누적 합) - (i-K 인덱스 누적합)

 

3. 구한 최대값을 출력한다.

 

 

<제출한 코드>

#include <iostream>
using namespace std;

int main(void){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int N, K;
    int max_sum = -1000;

    cin >> N >> K;
    int arr[N + 1];

    for (int i = 1; i <= N; i++){
        cin >> arr[i];
    }

    for (int i = 1; i <= N; i++){ // i번째 인덱스의 누적 합
        arr[i] = arr[i-1] + arr[i];
    }
    
    for (int i = K; i <= N; i++){ // 모든 연속된 K일의 합들 중 최대인 합을 구한다.
        if (max_sum < (arr[i] - arr[i-K])) max_sum = arr[i] - arr[i-K];
    }

    cout << max_sum;
    
    return 0;
}