문제 출처

1. 문제설명


  • 자세한 설명은 문제 링크 참조
  • 명령어를 구현해보자
    • recommend $G$ $x$ 
      • $x$가 1인 경우 추천 문제 리스트에서 알고리즘 분류가 $G$인 문제 중 가장 어려운 문제 번호를 출력한다.
      • 조건을 만족하는 문제가 여러 개라면 그 중 문제 번호가 큰 것으로 출력한다. 
      • $x$가 -1인 경우 추천 문제 리스트에서 알고리즘 분류가 $G$인 문제 중 가장 쉬운 문제 번호를 출력한다.
      • 조건을 만족하는 문제가 여러 개라면 그 중 문제 번호가 작은 것으로 출력한다.
      • 해당 명령어는 해당 그룹 $G$에 문제 번호가 한 개 이상이 있을 경우에만 주어진다.
    • recommend2 $x$
      • $x$가 1인 경우 추천 문제 리스트에서 알고리즘 분류 상관없이 가장 어려운 문제 번호를 - 출력한다.
      • 조건을 만족하는 문제가 여러 개라면 그 중 문제 번호가 큰 것으로 출력한다. 
      • $x$가 -1인 경우 추천 문제 리스트에서 알고리즘 분류 상관없이 가장 쉬운 문제 번호를 - 출력한다.
      • 조건을 만족하는 문제가 여러 개라면 그 중 문제 번호가 작은 것으로 출력한다.
    • recommend3 $x$ $L$ - $x$가 1인 경우 추천 문제 리스트에서 알고리즘 분류 상관없이 난이도 $L$보다 크거나 같은 문제 중 가장 쉬운 문제 번호를 출력한다.
      • 조건을 만족하는 문제가 여러 개라면 그 중 문제 번호가 작은 것으로 출력한다. 만약 조건을 만족하는 문제 번호가 없다면 -1을 출력한다.
      • $x$가 -1인 경우 추천 문제 리스트에서 알고리즘 분류 상관없이 난이도 $L$보다 작은 문제 중 가장 어려운 문제 번호를 출력한다.
      • 조건을 만족하는 문제가 여러 개라면 그 중 문제 번호가 큰 것으로 출력한다. 만약 조건을 만족하는 문제 번호가 없다면 -1을 출력한다.
    • add $P$ $L$ $G$
      • 추천 문제 리스트에 난이도가 $L$이고 알고리즘 분류가 $G$인 문제 번호 $P$를 추가한다. (추천 문제 리스트에 없는 문제 번호 $P$만 입력으로 주어진다. 이전에 추천 문제 리스트에 있던 문제 번호가 다른 난이도와 다른 알고리즘 분류로 다시 들어 올 수 있다.)
    • solved $P$
      • 추천 문제 리스트에서 문제 번호 $P$를 제거한다. (추천 문제 리스트에 있는 문제 번호 $P$만 입력으로 주어진다.)


2. 알고리즘 설계


  • set을 이용해 풀이하였다.
  • 문제를 보면, 1. 알고리즘 분류 및 난이도에 따라 2. 알고리즘 난이도에 따라 로 나뉜다.
    • 각각을 set 배열로 선언해주면 된다.
  • 알고리즘 문제 번호, 분류, 난이도를 모두 담은 pair<int,int>형 배열도 필요하다.
  • 나머지는 이전 문제와 마찬가지로 iterator를 움직여주면 된다.
    • 움직이는 건 이전 문제에 자세히 설명했으니 생략하겠다.


3. 전체 코드


#include <bits/stdc++.h>
using namespace std;
using pii = pair<int,int>;

int N, P, M, L, G, x;
pii problem[100'005];
set<int> lv[105];
set<int> cls_lv[105][105];

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> N;
    while(N--) {
        cin >> P >> L >> G;
        problem[P] = {G, L};
        lv[L].insert(P);
        cls_lv[G][L].insert(P);
    }

    cin >> M;
    while(M--) {
        string opt;
        cin >> opt;

        if(opt == "recommend") {
            int num, cmp;
            cin >> G >> x;

            if(x == 1) {
                for(int i=100; i>0; i--) {
                    if(cls_lv[G][i].empty()) continue;
                    cout << *prev(cls_lv[G][i].end()) << '\n';
                    break;
                }
            }
            else {
                for(int i=1; i<=100; i++) {
                    if(cls_lv[G][i].empty()) continue;
                    cout << *cls_lv[G][i].begin() << '\n';
                    break;
                }
            }
        }
        else if(opt == "recommend2") {
            cin >> x;

            if(x == 1) {
                for(int i=100; i>0; i--) {
                    if(lv[i].empty()) continue;
                    cout << *prev(lv[i].end()) << '\n';
                    break;
                }
            }
            else {
                for(int i=1; i<=100; i++) {
                    if(lv[i].empty()) continue;
                    cout << *lv[i].begin() << '\n';
                    break;
                }
            }
        }
        else if(opt == "recommend3") {
            int flag = false;
            cin >> x >> L;

            if(x == 1) {
                for(int i=L; i<=100; i++) {
                    if(lv[i].empty()) continue;
                    cout << *lv[i].begin() << '\n';
                    flag = true;
                    break;
                }
                if(!flag) cout << "-1\n";
            }
            else {
                for(int i=L-1; i>0; i--) {
                    if(lv[i].empty()) continue;
                    cout << *prev(lv[i].end()) << '\n';
                    flag = true;
                    break;
                }
                if(!flag) cout << "-1\n";
            }
        }
        else if(opt == "add") {
            cin >> P >> L >> G;
            problem[P] = {G, L};
            lv[L].insert(P);
            cls_lv[G][L].insert(P);
        }
        else {
            cin >> P;
            pii cur = problem[P];
            cls_lv[cur.first][cur.second].erase(P);
            lv[cur.second].erase(P);
        }
    }

    return 0;
}