Language/C++

[c++][백준 21944][multiset + map] 문제 추천 시스템 Version2 - 컴도리돌이

컴도리돌이 2022. 3. 4. 18:00
728x90

 

 

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

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

www.acmicpc.net


해당 문제는 저번 포스팅에 언급한 version 1가 유사하게 풀었다. 문제에서 알고리즘 분류, 전체 문제, 난이도의 크기에 따라 문제 번호를 출력을 요구했기에 version 1 문제 보다는 map함수와 multiset 함수를 조금 더 사용하였다. 요번 포스팅은 함수의 쓰임만 언급하겠다..

 

  • 1. map<int,multiset<pair<int,int>>> group   그룹에서 가장 어려운 문제 또는 쉬운 문제를 출력하는 명령어가 있기에 그룹에 해당한 번호에 대해 난이도와 문제 번호를 맵핑 시켰다. 그중에서도 난이도에 따른 정렬을 하기 위해 multiset을 이용하였다.
  • 2. multiset<pair<int,int>> level  알고리즘 분류와 상관 없이 난이도에 따른 어렵고, 쉬운 문제를 출력하는 명령어가 있기에 해당 함수를 만들었고, 난이도에 따른 정렬을 하기 위해 multiset 함수를 이용했다.
  • 3. map<int,pair<int,int>> find_value_map 해당 map 함수는 단지 위에 언급한 group, level 함수에 있는 값을 용이하게 삭제하기 위해 구현한 것이다. 그 이상 이하도 없다.

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<set>
#include<tuple>
#include<map>


using namespace std;

map<int,multiset<pair<int,int>>> group;
multiset<pair<int,int>> level;
map<int,pair<int,int>> find_value_map;

void solve(string s){
    if(s == "recommend"){
        int g,x;
        cin >> g >> x;

        if(x == 1){
            //알고리즘 분류가 g인 문제 중 가장 어려운 문제
            // 여러 개라면 그중 문제 번호가 큰 것
            cout << prev(group[g].end())->second << '\n';
        }
        else if(x== -1){
            // 1가 반대
            cout << group[g].begin()->second << '\n';
        }
    }
    else if(s == "recommend2"){
        int x;
        cin >> x;
        if(x == 1){
            //알고리즘 분류와 상관 없이 가장 어려운 문제
            cout << prev(level.end())->second << '\n';
        }
        else if(x == -1){
            // 반대
            cout << level.begin()->second << '\n';
        }
    }
    else if(s == "recommend3"){
        int x,l;
        cin >> x >> l;
        //조건 만족하는 문제 번호 없으면 -1출력.
        if(x == 1){
            //알고리즘 분류 x 난이도 l보다 크거나 같은 문제 중 가장 쉬운 문제
            auto it = level.lower_bound({l,-1e9});
            if(it != level.end()) cout << it->second << '\n';
            else cout << -1 << '\n';
            
        }
        else if(x == -1){
            //반대
            auto it = level.upper_bound({l,-1e9});
            if(it != level.begin()) cout << (--it)->second << '\n';
            else cout << -1 << '\n';
        }
    }
    else if(s == "add"){
        int p,l,g;
        cin >> p >> l >> g;
        group[g].insert({l,p});
        level.insert({l,p});
        find_value_map[p] = {l,g};
    }
    else if(s == "solved"){
        int p;
        cin >> p;
        int l = find_value_map[p].first;
        int g = find_value_map[p].second;
        group[g].erase({l,p});
        level.erase({l,p});
        find_value_map.erase(p);
    }
    return;
}

void solution(){

    ios_base::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int n,m;
    
    cin >> n;
    for(int i=0,p,l,g; i<n; i++){
        cin >> p >> l >> g;
        group[g].insert({l,p});
        level.insert({l,p});
        find_value_map[p] = {l,g};
    }
    cin >> m;
    for(int i=0; i< m; i++){
        string input;
        cin >> input;
        solve(input);
    }
}

int main(void){
    solution();
    return 0;
}