수열

동동·2023년 4월 9일
0

[C++] 백준 문제 풀이

목록 보기
24/32
post-thumbnail

수열

날짜: 2023년 4월 9일 오후 8:39
문제번호: 2559
알고리즘: 누적 합, 슬라이딩 윈도우, 투 포인터
키워드: 누적합, 슬리이딩 윈도우

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초128 MB35089128091026135.828%

문제

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

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

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

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

https://upload.acmicpc.net/563b6bfd-12ff-4275-a869-90fdd43b6deb/-/preview/

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

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

https://upload.acmicpc.net/cb8d846c-2f90-475a-8901-1fb69de87397/-/preview/

이때, 온도의 합이 가장 큰 값은 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

풀이

#include <iostream>

using namespace std;

int main() {

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n,k;
    cin>>n>>k;
    int temp[n];
    for(int i=0; i<n; i++) {
        cin>>temp[i];
    }

    int max = -1000;
    for(int i=0; i<n-(k-1); i++) {
        int sum = 0;
        for(int j=i; j<i+k; j++) {
            if(i+k>n)
                break;
            sum+= temp[j];
        }
        if(sum > max)
            max = sum;
    }

    cout<<max;

}

이렇게 했더니 시간초과가 났다.

위코드는 시간복잡도가 o(n^2)이라서 초과가 나는 것

투 포인터를 통해 o(n)으로 구할 수 있다.

#include <iostream>

using namespace std;

int main() {

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int arr[100001];

    int n,k;
    cin>>n>>k;

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

    int start = 0;
    int sum = 0;
    int max = -999999;

    //누적 합 계산
    for (int i=0; i<n; i++) {
        sum += arr[i];

        if(i >= k - 1) { // i가 k범위를 넘어서려하면? 말이 좀 헷갈림
            if(max < sum) //max 갱신
                max = sum;
            sum -= arr[start++]; //슬라이딩 윈도우의 맨 앞 원소를 빼주고 맨 앞 원소 index 갱신
        }
    }

    cout << max;

}
profile
알고리즘 문제를 주로 업로드합니다.

0개의 댓글