ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Algorithm] 프로그래머스 C++ : 베스트앨범
    Algorithm 2020. 7. 14. 03:01

     

     

     

     

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

     

    코딩테스트 연습 - 베스트앨범

    스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다. 속한 노래가 ��

    programmers.co.kr

    매우 고려하기 복잡했던 문제

     

    나는 일단 내가 원하는 대로 vector를 만들어서 하나씩 정렬해갔다.

     

    주어진 genres, plays를 하나로 합친 vector => v

     

    v의 형식은 (플레이횟수, (고유번호, 장르))로 했다.

     

    v를 sort로 정렬하게 되면, 플레이 횟수로 v가 정렬된다.

    나중에 "장르 내에서 많이 재생된 노래를 먼저 수록합니다." 조건을 만족시킬 수 있게 됐다.

     

    그런 다음에 "속한 노래가 많이 재생된 장르를 먼저 수록합니다." 만족시키기 위해, genres vector를 중복 원소가 없도록 제거했다.

     

    이제 중복 원소가 제거된 genres를 가지고 v를 돌면서 어떤 장르가 많이 재생됐는지 genres_sum에 (재생수, 장르) 형식으로 저장했다.

     

    마지막으로 genres_sum에 저장된 장르 순서대로 v를 돌면서 많이 재생된 장르 내에서 많이 재생된 노래를 answer에 삽입했다.

     

    ** 여기서 고려해야할점

    1. "스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다.

    > 두 개씩만 answer에 넣어야 해서 하나씩 answer에 삽입할 때마다 flag를 1씩 증가시켰다. flag가 3이 되면 세 번째 노래이므로 break

     

    2. "장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다."을 만족시켜야 한다.

    > 그래서 flag == 2일때, 즉 두 번째 노래를 삽입할 때 이전에 삽입했던 노래와 재생 횟수가 같은데 현재 고유번호가 더 낮은 수라면 swap해줬다.

     

    Code

    #include <string>
    #include <vector>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    vector<int> solution(vector<string> genres, vector<int> plays) {
        vector<int> answer;
        
        vector<pair<int, pair<int, string>>> v;
        
        for(int i=0; i<genres.size(); i++) {
            v.push_back(make_pair(plays[i], make_pair(i, genres[i])));
        }
        
        // 내림차순 정렬 - 장르 내에서 많이 재생된 노래를 먼저 수록 위해
        sort(v.begin(), v.end());
        reverse(v.begin(), v.end());
        
        //for(int i=0; i<v.size(); i++) {
        //    cout << "v1 : " << v[i].first << "\n";
        //    cout << "v2 : " << v[i].second.first << "\n";
        //    cout << "v3 : " << v[i].second.second << "\n";
        //}
        
        // genres 원소 중복 제거
        sort(genres.begin(), genres.end());
        genres.erase(unique(genres.begin(), genres.end()), genres.end());
        
        vector<pair<int, string>> genres_sum;
    
        // 많이 재생한 장르 찾기
        for(string g : genres) {
            int sum = 0;
            for(int i=0; i<v.size(); i++) {
                if(g == v[i].second.second) {
                    sum += v[i].first;
                }
            }
            genres_sum.push_back(make_pair(sum, g));
        }
        
        // 내림차순 정렬 - 속한 노래가 많이 재생된 장르를 먼저 수록 위해
        sort(genres_sum.begin(), genres_sum.end());
        reverse(genres_sum.begin(), genres_sum.end());
        
        int flag = 1, before_listen, before_idx;
        
        for(int j=0; j<genres_sum.size(); j++) {
            for(int i=0; i<v.size(); i++) {
                if(flag == 3) break;
                if(flag == 1) {
                    before_listen = v[i].first;
                    before_idx = v[i].second.first;
                }
                if(genres_sum[j].second == v[i].second.second) {
                    // 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록
                    if(flag == 2 && before_listen == v[i].first && before_idx > v[i].second.first) {
                        int tmp = answer.back();
                        answer.pop_back();
                        answer.push_back(v[i].second.first);
                        answer.push_back(tmp);
                    }
                    else {
                        answer.push_back(v[i].second.first);
                    }
                    flag += 1;
                }
            }
            flag = 1;
        }
        
        //for(int i=0; i<answer.size(); i++) {
            //cout << "answer : " << answer[i] << "\n";
        //}
        
        return answer;
    }

    댓글

dokylee's Tech Blog