https://www.acmicpc.net/problem/21939
21939번: 문제 추천 시스템 Version 1
tony9402는 최근 깃헙에 코딩테스트 대비 문제를 직접 뽑아서 "문제 번호, 난이도"로 정리해놨다. 깃헙을 이용하여 공부하시는 분들을 위해 새로운 기능을 추가해보려고 한다. 만들려고 하는 명령
www.acmicpc.net
#include <iostream>
#include <queue>
#include <map>
using namespace std;
priority_queue<pair<int, int>, vector<pair<int, int>>, less<pair<int, int>>> lpq; //{난이도, 문제 번호}, 최댓값
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> gpq; //{난이도, 문제 번호}, 최솟값
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, m;
cin >> n;
map<int, bool> isExist; //문제 번호, 있는지 여부
for (int i = 0; i < n; i++) {
int p, l;
cin >> p >> l;
lpq.push(make_pair(l, p));
gpq.push(make_pair(l, p));
isExist[p] = true;
}
cin >> m;
for (int i = 0; i < m; i++) {
string opt;
cin >> opt;
// x가 1인 경우 추천 문제 리스트에서 가장 어려운 문제의 번호를 출력한다.
// 만약 가장 어려운 문제가 여러 개라면 문제 번호가 큰 것으로 출력한다.
// x가 -1인 경우 추천 문제 리스트에서 가장 쉬운 문제의 번호를 출력한다.
// 만약 가장 쉬운 문제가 여러 개라면 문제 번호가 작은 것으로 출력한다.
if (opt.compare("recommend") == 0) {
int x;
cin >> x;
switch(x) {
case 1:
cout << lpq.top().second << "\n";
break;
case -1:
cout << gpq.top().second << "\n";
break;
}
}
//추천 문제 리스트에 난이도가 L인 문제 번호 P를 추가한다. (추천 문제 리스트에 없는 문제 번호
//P만 입력으로 주어진다. 이전에 추천 문제 리스트에 있던 문제 번호가 다른 난이도로 다시 들어 올 수 있다.)
else if (opt.compare("add") == 0) {
int p, l;
cin >> p >> l;
lpq.push(make_pair(l, p));
gpq.push(make_pair(l, p));
isExist[p] = true;
}
/* 추천 문제 리스트에서 문제 번호
P를 제거한다. (추천 문제 리스트에 있는 문제 번호
P만 입력으로 주어진다.)*/
else if (opt.compare("solved") == 0) {
int p;
cin >> p;
isExist[p] = false;
//삭제 값이 top에 남아있지 않도록 처리
while (!gpq.empty() && isExist[gpq.top().second] == false) {
gpq.pop();
}
while (!lpq.empty() && isExist[lpq.top().second] == false) {
lpq.pop();
}
}
}
return 0;
}
recommend 옵션에서 x에 따라 최댓값, 최솟값을 출력해야 하므로 이중 우선순위 큐의 응용문제이다.
우선순위 큐에는 {난이도, 문제번호} 순으로 pair를 넣어 난이도 순, 난이도가 같을 경우 문제번호 순으로 정렬되도록 한다.
map<문제 번호, 존재 여부> 로 해당 문제의 존재 유무를 확인한다.
1. recommend: 주어진 x에 따라 최댓값, 최솟값을 우선순위 큐의 top을 참조하여 출력한다.
2. add: 처음 문제 리스트 입력과 똑같이 구현한다.
3. solved: 이걸 구현하는 게 핵심이었다고 생각한다. 주어진 문제를 제거한다. 해당 문제의 존재 여부를 false로 만든다. 이후 lpq, gpq에 해당 문제가 top으로 되어있다면 recommend 연산에서 이미 지워진 문제가 출력될 수 있으므로 각 큐의 top에 해당 문제가 존재하지 않는다면 pop하여 top의 문제를 제거한다.
이렇게 하면 만약 각 큐의 top이 아닌 문제를 제거하더라도 해당 문제 앞의 값이 모두 지워진다면 이 연산에서 해당 문제도 지워지게 된다.
'Coding Test' 카테고리의 다른 글
| 백준 4256 트리 (1) | 2024.04.07 |
|---|---|
| 백준 4195 친구 네트워크 (3) | 2024.04.06 |
| 백준 2346 풍선 터뜨리기 (0) | 2024.04.04 |
| 백준 16937 두 스티커 (2) | 2024.04.03 |
| 백준 2512 예산 (0) | 2024.04.02 |