문제 설명
n개의 음이 아닌 정수들이 있습니다. 이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.
-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3
사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.
제한사항
주어지는 숫자의 개수는 2개 이상 20개 이하입니다.
각 숫자는 1 이상 50 이하인 자연수입니다.
타겟 넘버는 1 이상 1000 이하인 자연수입니다.
사실 DFS!라기 보다는 재귀함수의 개념을 생각하며 푼 문제였다. 주어진 숫자를 기준으로 picked 배열에 뽑을 수 있는 두 가지 경우를 생각해서 자기 함수를 불러오며 뽑을 만큼 뽑았을 때 그 합을 target과 비교하는 것이다.
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int pick(int n, int k, vector<int> numbers, int* picked, int target){
int cnt = 0;
if(k == n){
for(int i = 0; i < n; i++){
cnt += picked[i];
}
if(cnt == target) return 1;
else return 0;
}
if(k + 1 > n) return 0;
// 더하는 경우
picked[k] = numbers[k]; // +1
cnt += pick(n, k + 1, numbers, picked, target);
// 빼는 경우
picked[k] = numbers[k] * -1; // -1
cnt += pick(n, k + 1, numbers, picked, target);
return cnt;
}
int solution(vector<int> numbers, int target) {
int answer = 0;
int size = numbers.size();
int* picked = new int[size];
answer += pick(size, 0, numbers, picked, target);
return answer;
}
하지만 굳이 picked를 쓰지 않고 매개변수에 sum을 넣어 매 시도마다 매개변수로 sum을 가져가서 확인하는 방법도 있다. 다음처럼 코드를 작성하면 훨씬 간단해진다.
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int dfs(int n, int k, vector<int> numbers, int sum, int target){
int cnt = 0;
if(k == n){
if(sum == target)
return 1;
return 0;
}
// 더하는 경우
cnt += dfs(n, k + 1, numbers, sum + numbers[k], target);
// 빼는 경우
cnt += dfs(n, k + 1, numbers, sum - numbers[k], target);
return cnt;
}
int solution(vector<int> numbers, int target) {
int answer = 0;
int size = numbers.size();
answer = dfs(size, 0, numbers, 0, target);
return answer;
}
'코딩테스트' 카테고리의 다른 글
[SQL] 평균 일일 대여 요금 구하기 (0) | 2024.03.20 |
---|---|
[SQL] 흉부외과 또는 일반외과 의사 목록 출력하기 (0) | 2024.03.20 |
[1758] 알바생 경호 (0) | 2024.02.22 |
[11508] 2 + 1세일 (0) | 2024.02.22 |
[18121] 문자열 압축 (0) | 2024.02.22 |
댓글