관리 메뉴

Mini

백준 1806 부분합 c++ // 투포인터, 누적합 구현방법 본문

Algorithm/투포인터

백준 1806 부분합 c++ // 투포인터, 누적합 구현방법

Mini_96 2023. 11. 6. 16:53

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

 

1806번: 부분합

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

www.acmicpc.net

1. 문제

누적합배열을 썻더니 오답이 나왔다.

최적해를 보장하지 않는것 같다.. (정렬이 안되서?)

 

1.1 해결 : tot 변수를 써서 누적합을 저장함

 

2. 의사코드 

1. total보다 S가 크면, en을 하나 늘려주고 total 변수에 arr[en]을 더한다. 
    (쉽게말해 total을 st~en -> st~en+1로 만드는 것)

2. total보다 S가 작으면, total 변수에 arr[st]를 빼고 st를 하나 늘려준다.
    (쉽게말해 total을 st~en -> st+1~en로 만드는 것)

 

3. 전체코드

// Authored by : BaaaaaaaaaaarkingDog
// Co-authored by : -
// http://boj.kr/ecc7d7f58ceb4679a1bb67adbb79088c
#include <bits/stdc++.h>
using namespace std;

int n, s, tot;
int a[100005];
int mn = 0x7fffffff;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> s;
    for (int i = 0; i < n; i++) cin >> a[i];
    tot = a[0];
    int en = 0;
    for (int st = 0; st < n; st++) {
        //tot<s 인경우 : en++, tot++ (st~en+1)로 만들기
        while (en < n && tot < s) {
            en++;
            if (en != n) tot += a[en];
        }
        if (en == n) break; //out of index check
        
        //tot>=s 인경우 : 정답갱신, tot-- (st+1~en)으로 만들기
        mn = min(mn, en - st + 1);
        tot -= a[st];
    }
    if (mn == 0x7fffffff) mn = 0;
    cout << mn;
}