1. 문제
https://programmers.co.kr/learn/courses/30/lessons/42579
코딩테스트 연습 - 베스트앨범
스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다. 속한 노래가
programmers.co.kr
해당 문제는 map, vector, priority_queue, compare()를 자유롭게 사용할 수 있어야 풀이가 쉬운 문제였다.
map을 vector로 복사하는 방법과 map의 value로 pq를 정의하고, sort()와 pq의 우선순위를 compare() 함수로 정의하는 방법을 익힐 수 있었다.
2. 풀이
1. 장르별 총 재생횟수를 map에 저장하였다. --> map<장르, 총count>
2. 위 map을 총 재생횟수를 기준으로 내림차순 정렬하기 위해 vector로 복사하였다. --> vector<장르, 총 count>
3. 내림차순으로 정렬된 벡터로부터 장르를 얻어온다.
4. 위에서 얻어온 장르 내에서 많이 재생된 2개의 노래를 탐색하기 위해 map을 정의하였다. key는 장르로, value는 우선순위 큐로 정의했다. --> map<key(장르),value(pq(pii<count, id>))>
4. 우선순위 큐는 장르내에서 가장 많이 재생된 노래 순으로, 만약 재생 횟수가 같다면 id 가 낮은 순으로 정의했다.
5. 우선순위 큐를 2번만 삭제하여 가장 많이 재생된 2곡을 answer에 저장하였다.
3. 코드
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
#define f first
#define s second
typedef pair<int, int> pii;
typedef pair<string, int> psi;
bool cmp(psi a, psi b) {
return (a.s > b.s);
}
// 우선순위1 : count 내림차순
// 우선순위2 : id 오름차순
struct cmp2 {
bool operator() (pii a, pii b) {
if (a.f == b.f)
return (a.s > b.s);
else
return (a.f < b.f);
}
};
// 장르별 총 재생횟수 저장 map<장르, 총count>
// 위 map을 vector로 복사 후 내림차순 정렬-> vector<장르, 총 count>
// 장르내 많이 재생된 2개 노래 탐색 -> map<key(장르),value(pq(pii<count, id>))>
// 장르내 많이 재생된 2개의 노래 id를 answer에 저장
vector<int> solution(vector<string> genres, vector<int> plays) {
vector<int> answer;
map<string, int> genre_map;
map<string, priority_queue<pii, vector<pii>, cmp2>> genre_queue;
// pq를 내림차순으로 하는 경우
// map<string, priority_queue<pii, vector<pii>, greater<pii>>> map_queue;
for (int id = 0; id < genres.size(); ++id) {
string genre = genres[id];
int play = plays[id];
genre_map[genre] += play;
genre_queue[genre].push(pii(play, id));
}
vector<psi> genre_vec(genre_map.begin(), genre_map.end());
sort(genre_vec.begin(), genre_vec.end(), cmp);
// for (psi p : genre_vec)
// printf("%s %d\n", p.f.c_str(), p.s);
for (psi p : genre_vec) {
string genre = p.f;
printf("%s %d\n", p.f.c_str(), p.s);
int n = 0;
while (!genre_queue[genre].empty()) {
pii cur = genre_queue[genre].top();
genre_queue[genre].pop();
printf("%d %d\n", cur.first, cur.second);
answer.push_back(cur.second);
n++;
if (n == 2)
break;
}
}
return answer;
}