본문 바로가기

algorithm/BOJ

백준 1806_부분합(C++)

 

www.acmicpc.net/problem/1806

 

1806번: 부분합

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

www.acmicpc.net

[문제 풀이]

투 포인터를 이용하여 문제를 풀었습니다.

 

이 문제는 입력으로 들어온 수열의 부분집합의 합이 S 이상이 되는 것 중, 가장 짧은 수열을 찾는 문제입니다. 전형적인 투 포인터 문제입니다. 

 

코드 설명

  • 투 포인터를 위해 pre_idx와 post_idx를 0으로 초기화 합니다.
  • sum의 값을 배열 첫 번째 값으로 초기화 합니다.
  • 초기화 해준 sum의 값이 S와 같으면 값 1을 출력 합니다. 아닌 경우 while문을 통해 세 가지의 경우로 분리해 answer를 구해줍니다.
  • sum이 같은 경우, 길이가 1이라면 값 1을 출력 합니다. 아닌 경우, 값을 비교하고 post_idx 값을 증가시켜주고 arr[post_idx]를 sum에 추가합니다.
  • sum이 S보다 큰 경우, 길이가 1이라면 값 1을 출력시켜줍니다. 아닌 경우 arr[pre_idx]를 sum에서 빼주고 pre_idx 값을 증가 힙니다. 또한, pre_idx가 post_idx를 넘어버린다면 초기화 합니다.
  • sum이 S보다 작은경우, post_idx를 증가시켜주고 post_idx가 N보다 크거나 같으면 break 합니다.

[코드]

#include<iostream>

using namespace std;

int N, S, answer = 987654321;

int arr[100001];

int main() {

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

	cin >> N >> S;

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

	int pre_idx = 0;
	int post_idx = 0;

	int sum = arr[0];

	if (sum == S) {
		cout << 1 << endl;
		return 0;
	}

	while (post_idx < N && pre_idx <= post_idx) {

		if (sum == S) {
			
			int length = post_idx - pre_idx + 1;
			if (length  == 1) {
				cout << 1 << endl;
				return 0;
			}

			if (answer > length)
				answer = length;

			post_idx++;
			sum += arr[post_idx];

				

		}
		else if (sum > S) {

			int length = post_idx - pre_idx + 1;
			if (length == 1) {
				cout << 1 << endl;
				return 0;
			}

			if (answer > length)
				answer = length;

			sum -= arr[pre_idx];
			pre_idx++;

			if (pre_idx > post_idx && pre_idx < N) {
				post_idx = pre_idx;
				sum = arr[pre_idx];
			}

		}
		else if (sum < S) {

			post_idx++;

			if (post_idx >= N)
				break;

			sum += arr[post_idx];

		}
	}


	if (answer == 987654321)
		answer = 0;
	cout << answer << endl;

	return 0;

}

 

 

'algorithm > BOJ' 카테고리의 다른 글

백준 7453_합이 0인 네 정수(C++)  (0) 2020.10.15
백준 2143_두 배열의 합(C++)  (0) 2020.10.10
백준 2096_내려가기(C++)  (0) 2020.10.08
백준 1072_게임(C++)  (0) 2020.10.06
백준 2805_나무 자르기(C++)  (0) 2020.10.06