본문 바로가기
알고리즘

백준 g2 21944 문제 추천 시스템 Version 2 c++

by kyj0032 2024. 3. 12.

https://www.acmicpc.net/problem/21944

 

21944번: 문제 추천 시스템 Version 2

recommend, recommend2, recommend3 명령이 주어질 때마다 문제 번호를 한 줄씩 출력한다. 주어지는 recommend, recommend2, recommend3 명령어의 총 개수는 최소 1개 이상이다.

www.acmicpc.net

 

문제 

문제 추천 시스템 Version 1(https://kyj0032.tistory.com/85)의 업그레이드버전

N개의 추천 문제 리스트가 주어진다. 각각 문제번호 P, 난이도 L, 알고리즘 분류 G를 가지고 있다.

M개의 명령어가 주어진다.

  • recommend G x
    • x==1이면 알고리즘이 G인 문제 중 난이도가 가장 높은 문제, 문제 번호가 가장 큰 수를 출력한다.
    • x==-1이면 알고리즘이 G인 문제 중 난이도가 가장 낮은 문제, 문제 번호가 가장 작은 수를 출력한다.
  • recommend2 x
    • x==1이면 G에 상관 없이 전체 문제 중 난이도가 가장 높은 문제, 문제 번호가 가장 큰 수를 출력한다.
    • x==-1이면 G에 상관 없이 전체 문제 중 난이도가 가장 낮은 문제, 문제 번호가 가장 작은 수를 출력한다.
  • recommend3 x L
    • x==1이면 난이도가 L이상인 문제 중 가장 난이도가 낮은 문제, 문제 번호가 작은 수 출력
    • x==-1이면 난이도가 L미만인 문제 중 가장 난이도가 높은 문제, 문제 번호가 큰 수 출력
  • add P L G
    • 문제번호가 P이고 난이도가 L, 알고리즘이 G인 문제를 추가한다.
  • solved P
    • 문제번호 P를 리스트에서 삭제한다.

 

전체 코드

/*boj g2 문제 추천 시스템 Version 2*/
#include <iostream>
#include <set>
#define MAXN 100005
using namespace std;

int N, M;
int probLevel[MAXN]; // probLevel[문제 번호] = 난이도
int probAlg[MAXN];   // algProb[문제 번호] = 알고리즘 번호

set<int> levelProb[102];          // levelProb[난이도] = 문제번호
set<pair<int, int>> algProb[102]; // algProb[알고리즘 번호] = <난이도, 문제번호> set
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N;
    for (int i = 0; i < N; i++) {
        int P, L, G;
        cin >> P >> L >> G;
        probLevel[P] = L;
        probAlg[P] = G;

        levelProb[L].insert(P);
        algProb[G].insert(make_pair(L, P));
    }

    cin >> M;
    while (M--) {
        string cmd;
        cin >> cmd;
        if (cmd == "recommend") {
            int G, x;
            cin >> G >> x;

            if (x == 1) { // 알고리즘 G 중 가장 어려운 것+문제번호가 큰 것
                cout << (*(prev(algProb[G].end()))).second << "\n";
            } else if (x == -1) { // 알고리즘 G 중 가장 쉬운 것+문제번호가 작은 것
                cout << (*(algProb[G].begin())).second << "\n";
            }
        } else if (cmd == "recommend2") {
            int x;
            cin >> x;
            if (x == 1) { // 가장 어렵고 문제 번호가 큰 문제
                for (int i = 100; i >= 0; i--) {
                    if (levelProb[i].empty()) continue;

                    cout << *(--levelProb[i].end()) << "\n";
                    break;
                }
            } else { // x == -1
                for (int i = 1; i <= 100; i++) {
                    if (levelProb[i].empty()) continue;

                    cout << *(levelProb[i].begin()) << "\n";
                    break;
                }
            }
        } else if (cmd == "recommend3") {
            int x, L;
            cin >> x >> L;

            bool flag = true;
            if (x == 1) { // L이상 중 최소, 문제번호 작은 것
                for (int i = L; i <= 100; i++) {
                    if (levelProb[i].empty()) continue;
                    flag = false;
                    cout << *(levelProb[i].begin()) << "\n";
                    break;
                }
            } else { // L미만 중 가장 어려운 것, 최대
                for (int i = L - 1; i >= 0; i--) {
                    if (levelProb[i].empty()) continue;
                    flag = false;
                    cout << *(--levelProb[i].end()) << "\n";
                    break;
                }
            }
            if (flag)
                cout << -1 << "\n";
        } else if (cmd == "add") {
            int P, L, G;
            cin >> P >> L >> G;

            levelProb[probLevel[P]].erase(P);
            algProb[probAlg[P]].erase({probLevel[P], P});

            probLevel[P] = L;
            probAlg[P] = G;
            levelProb[L].insert(P);
            algProb[G].insert({L, P});
        } else if (cmd == "solved") {
            int P;
            cin >> P;

            levelProb[probLevel[P]].erase(P);
            algProb[probAlg[P]].erase({probLevel[P], P});
            probLevel[P] = 0;
            probAlg[P] = 0;
        }
    }
}