아래와 같이 5와 사칙연산만으로 12를 표현할 수 있습니다.
12 = 5 + 5 + (5 / 5) + (5 / 5)
12 = 55 / 5 + 5 / 5
12 = (55 + 5) / 5
5를 사용한 횟수는 각각 6,5,4 입니다. 그리고 이중 가장 작은 경우는 4입니다.
이처럼 숫자 N과 number가 주어질 때, N과 사칙연산만 사용해서 표현 할 수 있는 방법 중 N 사용횟수의 최솟값을 return 하도록 solution 함수를 작성하세요.
| N | number | return |
|---|---|---|
| 5 | 12 | 4 |
| 2 | 11 | 3 |
std::unordered_set 자료구조를 통해 저장을 했고, 먼저 5, 55, 555...를 저장했다.O(N^4) 정도로 기하급수적으로 매우 높을 것으로 보이지만, unordered_set을 통해서 중복 제거를 하기 때문에 충분히 통과가 가능한 것으로 보인다. #include <string>
#include <vector>
#include <unordered_set>
using namespace std;
int solution(int N, int number) {
int answer = -1;
vector<unordered_set<int>> NSets(9);
int temp = N;
// 5, 55, 555... 먼저 삽입
for(int i = 1; i <= 8; i++){
if(temp == number){
return i;
}
NSets[i].insert(temp);
temp = temp * 10 + N;
}
int plus, minus1, minus2, mult, div;
int l, r;
// 기존에 저장해놨던 값들을 통해 N을 사용한 횟수별로 사칙연산을 통해 값을 구하기
for(int i = 2; i <= 8; i++){
for(int j = 1; j * 2 <= i; j++){
for(auto it1 = NSets[i - j].begin(); it1 != NSets[i - j].end(); ++it1){
for(auto it2 = NSets[j].begin(); it2 != NSets[j].end(); ++it2){
l = *it1; r = *it2;
plus = l + r;
minus1 = l - r;
minus2 = r - l;
mult = l * r;
if (plus == number || minus1 == number
|| minus2 == number || mult == number) return i;
NSets[i].insert(plus);
NSets[i].insert(minus1);
NSets[i].insert(minus2);
NSets[i].insert(mult);
if(r != 0){
div = l / r;
if(div == number) return i;
NSets[i].insert(div);
}
if(l != 0){
div = r / l;
if(div == number) return i;
NSets[i].insert(div);
}
}
}
}
}
return answer;
}