ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스] 메뉴 리뉴얼
    Algorithm/구현(Brute force, Back tracking, etc.) 2021. 12. 29. 07:21
    728x90

    https://programmers.co.kr/learn/courses/30/lessons/72411

     

    코딩테스트 연습 - 메뉴 리뉴얼

    레스토랑을 운영하던 스카피는 코로나19로 인한 불경기를 극복하고자 메뉴를 새로 구성하려고 고민하고 있습니다. 기존에는 단품으로만 제공하던 메뉴를 조합해서 코스요리 형태로 재구성해서

    programmers.co.kr

     

    구현, 백트래킹, hash 문제이다. 백트래킹을 사용할 때, 주어진 문제의 조건을 반드시 확인해야 한다. 문자열의 길이가 최대 10이므로, 조합에 대한 경우의 수는 10Cr * 20( 2 <= r <= 10) 이기 때문에, 백트래킹을 사용할 수 있다.

     

    - 전체적인 풀이방식은,

     

    1. 먼저, course에 적힌 숫자들이 r이 된다. 그래서 모든 order에 대해서 각각 나올수 있는 r개의 조합을 구한다.

     

    2. course가 2인 경우, 각각의 order에서 나오는 r개의 조합을 찾는다. 이 때, 중복을 허용하지 않도록 dfs을 구현해야 

    한다. 이 과정에서, 필자는 unordered_map을 통해 해당 조합이 몇 번 등장 했는 지를 hash로 구현했다. 또, 처음 hash에 들어갈 때 all_string 벡터에 해당 조합을 push했다.

     

    3. 모든 order에 대해서 모든 2개의 조합을 다 찾았다면, all_string에 넣어두었던 이 조합들을 활용해서, 가장 많이 

    등장한 조합을 찾았다. 특정 조합의 해쉬 값이 현재 까지의max보다 더 큰 경우, 새로 max를 갱신하고, temp_v 벡터를 clear 하고 해당 조합을 새로 temp_v에 넣어주었다. 만약 max값과 동일한 경우, 정답 조합을 담을 temp_v 벡터에 넣어주었다. 

     

    4. 마지막으로 temp_v벡터의 모든 조합들을 answer벡터에 넣어준다. 

     

    5. 이 과정을 모든 course에 대해 진행하고, 마지막으로 한 번 더 sort를 해 주면 끝

     

    - 처음에 3번 테케를 통과하지 못해서 어떤 문제가 있을 지를 찾아보다가, 글자를 sorting 하지 않았다는 것을 깨달았다. 즉, 문제에서 WX와 XW를 동일한 조합으로 보았기 때문에, 처음에 특정 order에 대해 dfs를 시작할 때 해당 문자들을 모두 오름차순으로 재정렬 해 주어야 하는 것이었다. 

    #include <string>
    #include <vector>
    #include <unordered_map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    vector<string> all_string;
    unordered_map <string,int> um;
    
    void dfs(int count, int target,int index, string s, string order){
        if(count == target){
            if(um.find(s) != um.end()) {
                um[s]++;
            } else{
                um.insert({s,1}); 
                all_string.push_back(s);
            }
            return;
        }
        for(int i = index; i < order.length();i++){
            dfs(count+1, target, i+1, s+order[i], order);
        }
    }
    vector<string> solution(vector<string> orders, vector<int> course) {
        vector<string> answer;
        for(int i = 0; i < course.size(); i++){
            for(int j = 0; j < orders.size(); j++){
                vector<char> temp_v;
                for(int k = 0; k < orders[j].length();k++) temp_v.push_back(orders[j][k]);
                sort(temp_v.begin(), temp_v.end());
                string sorted_s;
                for(int k = 0; k < orders[j].length();k++) sorted_s+=temp_v[k];
                dfs(0,course[i], 0,"", sorted_s);
            }
            int max_num = 0; vector<string> temp_answers;
            for(int j = 0; j < all_string.size(); j++){
                if(um[all_string[j]] > 1 && um[all_string[j]] > max_num){ // max값 갱신
                    max_num = um[all_string[j]];
                    temp_answers.clear();
                    temp_answers.push_back(all_string[j]);
                }
                else if (um[all_string[j]] == max_num && um[all_string[j]] > 1) {
                    temp_answers.push_back(all_string[j]);
                } 
            }
            for(int j = 0; j < temp_answers.size(); j++) answer.push_back(temp_answers[j]);
            all_string.clear(); um.clear();
        }
        sort(answer.begin(), answer.end());
        return answer;
    }

    댓글

Designed by Tistory.