어흥

[백준 14225] 부분수열의 합 (C++) 본문

알고리즘/백준

[백준 14225] 부분수열의 합 (C++)

라이언납시오 2020. 4. 5. 09:54
728x90
반응형

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

 

14225번: 부분수열의 합

수열 S가 주어졌을 때, 수열 S의 부분 수열의 합으로 나올 수 없는 가장 작은 자연수를 구하는 프로그램을 작성하시오. 예를 들어, S = [5, 1, 2]인 경우에 1, 2, 3(=1+2), 5, 6(=1+5), 7(=2+5), 8(=1+2+5)을 만들 수 있다. 하지만, 4는 만들 수 없기 때문에 정답은 4이다.

www.acmicpc.net

1. 주의할 점

- 부분수열의 합으로 만들어 지는 수에 대해 중복 처리가 필요하다(따로 값을 저장할 시)

 

2. 구현

- Set을 이용해 부분수열의 합을 저장한다

- Cal() 함수의 경우 부분수열로 만들 수 있는 모든 수를 Set에 저장한다

- Set의 N번째와 N+1번째에 저장된 수의 차이가 1을 넘으면 N번째 수 +1을 출력한다

- Set의 Iterator를 통해 Set의 첫 번째 수가 1이 아니면 1을 출력하도록 한다

- Set에 저장된 모든 수가 1의 차이를 가지면, Set에 저장된 최댓값 +1을 출력한다

 

#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int num, arr[20];
set<int> s;

void cal(int idx, int sum) {
	if(idx == num) return;
	sum += arr[idx];
	if (s.find(sum) == s.end())		s.insert(sum);
	cal(idx + 1, sum);		//포함 하는 경우
	cal(idx + 1, sum-arr[idx]);		//포함 안하는 경우
}

int main() {
	cin >> num;
	for (int i = 0; i < num; i++) {
		cin >> arr[i];
		s.insert(arr[i]);
	}
	cal(0, 0);
	set<int> ::iterator it1 = s.begin(), it2;
	if (*it1 != 1) cout << 1;
	else {
		bool avail = false;
		while (1) {
			it2 = ++it1;
			if (it2 == s.end()) break;
			--it1;
			int a = *it2;
			int b = *it1;
			if (a - b != 1) {
				cout << b + 1;
				avail = true;
				break;
			}
			else
				it1 = it2;
		}
		if (!avail) {
			it2 = s.end();
			--it2;
			int result = *it2;
			cout << result + 1;
		}
	}
	system("pause");
	return 0;
}
728x90
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 10422] 괄호 (C++)  (0) 2020.04.07
[백준 2225] 합분해 (C++)  (0) 2020.04.06
[백준 1826] 연료 채우기 (C++)  (0) 2020.04.04
[백준 1715] 카드 정렬하기 (C++)  (0) 2020.04.04
[백준 2636] 치즈 (C++)  (0) 2020.04.04
Comments