본문 바로가기

백준/골드

[백준 1806번] 부분합 (C++)

문제링크 : https://www.acmicpc.net/problem/1806

 

1806번: 부분합

첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.

www.acmicpc.net

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAX = 987654321;

int arr[100001];

int main()
{
    ios_base::sync_with_stdio(0); 
	cin.tie(0);
    
    int N, S;
    cin >> N >> S;

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

    int s = 0, e = 0;
    int sum = arr[s];
    int result = MAX;

    while(e<N) //배열 끝까지 탐색
    {
        if(sum < S) sum+=arr[++e]; //뒤에 값 이동
        else 
        {
            result = min(result, e-s+1); //길이 저장
            sum-=arr[s++]; //앞에 값 이동
        }
    }
    cout << (result == MAX ? 0 : result);
    return 0;
}

두 포인터를 사용해 푸는 누적합 문제이다.

처음에 포인터를 둘다 0, 0으로 시작하여 뒷 포인터 부터 움직이면서 합을 체크해주면 된다.

 

먼저 현재 합이 S미만 이라면 현재 합에 다음 위치 값을 더해준다.

현재 합이 S이상이라면 최소 길이를 저장해주는 동시에 다른 범위 탐색을 위해서 앞 포인터를 한 칸 뒤로 옮겨준다.

 

이를 반복하며 현재 합이 S이상일 때 최소 길이를 추려준다.

'백준 > 골드' 카테고리의 다른 글

[백준 2467번] 용액 (C++)  (0) 2023.08.26
[백준 2166번] 다각형의 면적 (C++)  (0) 2023.08.25
[백준 27172번] 수 나누기 게임 (C++)  (0) 2023.08.23
[백준 2638번] 치즈 (C++)  (0) 2023.08.22
[백준 1238번] 파티 (C++)  (0) 2023.08.21