ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [DP] N으로 표현
    Study/Coding Test 2021. 2. 18. 15:31

    programmers.co.kr/learn/courses/30/lessons/42895

     

    코딩테스트 연습 - N으로 표현

     

    programmers.co.kr

    문제 설명

    아래와 같이 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은 1 이상 9 이하입니다.
    • number는 1 이상 32,000 이하입니다.
    • 수식에는 괄호와 사칙연산만 가능하며 나누기 연산에서 나머지는 무시합니다.
    • 최솟값이 8보다 크면 -1을 return 합니다.

    입출력 예

    N number return
    5 12 4
    2 11 3

    입출력 예 설명

    예제 #1
    문제에 나온 예와 같습니다.

    예제 #2
    11 = 22 / 2와 같이 2를 3번만 사용하여 표현할 수 있습니다.

     


    Sol) DP

    1. vector < set<int>> : 숫자N을 사용했을때 경우의 수를 넣을 set들의 집합.

    - 마지막에 find 함수를 쓰기 위해 vector 대신 set 사용

    2. N개의 숫자를 x번 사용한 경우

    - 5를 두번 사용하면 55

    3. (1번 set 과 (n-1) set)  U (2번 set 과 (n-2) set)  U ... ((n-1)번 set 과 1번 set)

    - 5를 3번 이용한 경우는 (1번과 2번) U (2번과 1번) 

    4. 숫자를 적게 사용한 경우부터 (벡터의 인덱스가 작은 순서) number를 찾는다.

     

    #include <string>
    #include <vector>
    #include <set>
    #include <cmath>
    #include <iostream>
    
    using namespace std;
    
    int get_basic_number(int N, int cnt) {
        int res = 0;
        
        while (cnt > 0) {
            cnt -= 1;
            res += N * pow(10, cnt);
        }
        
        return res;
    }
    
    int solution(int N, int number) {
        if (N == number) {
            return 1;
        }
        
        int answer = -1;
        const int MIN = 8;
        
        vector<set<int>> s (MIN);
       
        int idx = 1;
        for (auto & x : s) {
            x.insert(get_basic_number(N, idx));
            idx += 1;
        }
        
        for (int i=1; i<MIN; i++) { 
            for (int j=0; j<i; j++) {
                for (const auto op1 : s[j]) {
                    for (const auto op2 : s[i-j-1]) {
                        s[i].insert(op1+op2);
                        s[i].insert(op1-op2);
                        s[i].insert(op1*op2);
                        
                        if (op2 != 0)
                            s[i].insert(op1/op2);
                    }
                }
            }
            
            if (s[i].find(number) != s[i].end()) {
                answer = i+1;
                break;
            }
        }
        
        return answer;
    }

     

     

     

    참고

    gurumee92.tistory.com/164

    'Study > Coding Test' 카테고리의 다른 글

    [DP] 등굣길  (0) 2021.02.21
    [2021 KAKAO] 광고 삽입  (0) 2021.02.18
    [2021 KAKAO] 합승 택시 요금  (0) 2021.02.17
    [삼성전자] 연구소  (0) 2021.02.15
    [2021 KAKAO] 메뉴 리뉴얼  (0) 2021.02.15
Designed by Tistory.