[BOJ]1806 부분합 C++

Min Kyu Jeon·2021년 7월 20일
1

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

문제
10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오.

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

출력
첫째 줄에 구하고자 하는 최소의 길이를 출력한다. 만일 그러한 합을 만드는 것이 불가능하다면 0을 출력하면 된다.

S를 만드는 것이 불가능할때의 예외처리를 생각하자
슬라이딩 윈도우를 이용하여 문제풀이
SUM을 계산할때 매번 해주지않고 단순히 포인트 변화에 대해서 빼고 더해주는 식으로 계산하면
더욱 효율적인 알고리즘이 된다.

#include <bits/stdc++.h>
using namespace std;


int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

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

	int l = 0; int r = 0; int ans = 987654321; int sum = arr[0];
	for (;;) {
		/*for (int i = l; i <= r; i++) {
			sum += arr[i];
		}*/
		if (sum >= S) {
			ans = min(ans, r - l + 1);
			sum -= arr[l++];
		}
		else if (sum < S) {
			sum += arr[++r];
		}
		if (r >= N) break;
	}
	if (ans == 987654321) ans = 0;
	cout << ans;

	return 0;
}

0개의 댓글