[Programmers] 순위 검색

bin1225·2022년 12월 26일
0

Algorithm

목록 보기
8/43

문제를 보고 처음 떠올린 방법은, 점수순으로 정보를 나열하고 정렬해서, 기준점수를 만족할 때까지만 조건을 확인하고 정답을 증가시키는 방법이었다.
info를 입력받을 때 반복문의 i값을 이용해서 점수,i값의 pair와 key가 i value가 정보배열인 map을 생성해서, 연관되는 정보를 찾을 수 있게 했다. 이렇게 하면 점수순서로 나열하고 map에서 정보를 찾아 비교할 수 있다.
솔직히 풀면서도 효율성 안 나올 것 같았는데 역시는 역시였다.

#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <algorithm>
using namespace std;

vector<int> solution(vector<string> info, vector<string> query) {
    vector<int> answer(query.size(),0);
    
    string lang,part,car,food;
    int score;
    vector<pair<int,int>> rank;
    unordered_map<int,vector<string>> infoMap;
    for(int i=0; i<info.size(); i++){
        istringstream iss(info[i]);
        iss>>lang>>part>>car>>food>>score;
        rank.push_back(make_pair(score, i));
        infoMap[i] = {lang,part,car,food};
    }
    
    sort(rank.begin(), rank.end());
    reverse(rank.begin(), rank.end());
    
    
    vector<string> v1,v2(4);
    string s;
    for(int i=0; i<query.size(); i++){
        istringstream iss(query[i]);
        iss>>lang>>s>>part>>s>>car>>s>>food>>score;
        v2[0] = lang; v2[1]=part; v2[2]=car; v2[3] = food;
        
        for(int j=0; j<rank.size(); j++){
            if(rank[j].first<score) break;
            v1= infoMap[rank[j].second];
            
            int k=0;
            for(; k<v1.size(); k++){ 
                if(v2[k]!="-" && v2[k] != v1[k]) break;
            }
            
            if(k==v1.size()){
                 answer[i]++;
            }
        }
        
    }
    
    
    return answer;
}

두 번째 방법은 솔직히 살짝 생각했다가, 확신도 안 서고 좀 오바 아닌가 라는 생각에 머뭇거렸는데, 질문하기를 뒤져보다가 이게 맞는 풀이 방법이라는 것을 알게 됐다.
처음 입력받을 때 info에 대한 정보를 해당되는 집합별로 분류하는 것이다. query에 "-"가 있을 걸 고려해서 4C3, 4C2, 4C1, 4C0 인 경우에 대해 score를 저장해두고, 나중에 이용하는 방식이다.

근데, 이 방법으로도 효율성이 통과가 안됐다.
핵심적인 아이디어는 적용한 것 같은데, 왜 안되지 싶어서 계속 질문하기에 있는 효율성 팁을을 참고했다.

첫번째는 sort를 map생성후에 해주는 것이다. 효율성 테스트에 있어서는 차라리 미리 다 해버리는 게 효율적인가보다.

두번째는 binary search를 이용하는 것이었는데, 이게 인덱스 어디로 갈지 생각하는 게 머리아파서 검색해보다가 lower_bound라는 함수를 알게 됐고 사용하였다.

#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <algorithm>
using namespace std;

vector<int> solution(vector<string> info, vector<string> query) {
    vector<int> answer(query.size(),0);
    
    string lang,part,car,food;
    int score;
    vector<pair<int,int>> rank;
    unordered_map<string,vector<int>> infoMap;
    for(int i=0; i<info.size(); i++){
        istringstream iss(info[i]);
        iss>>lang>>part>>car>>food>>score;
        infoMap[lang+part+car+food].push_back(score);
        infoMap[part+car+food].push_back(score);
        infoMap[lang+car+food].push_back(score);
        infoMap[lang+part+food].push_back(score);
        infoMap[lang+part+car].push_back(score);
        infoMap[lang+part].push_back(score);
        infoMap[lang+car].push_back(score);
        infoMap[lang+food].push_back(score);
        infoMap[part+car].push_back(score);
        infoMap[part+food].push_back(score);
        infoMap[car+food].push_back(score);
        infoMap[lang].push_back(score);
        infoMap[part].push_back(score);
        infoMap[car].push_back(score);
        infoMap[food].push_back(score);
        infoMap[""].push_back(score);
    
    }
    
    vector<string> v(4);
    string s;
    for(int i=0; i<query.size(); i++){
        istringstream iss(query[i]);
        iss>>lang>>s>>part>>s>>car>>s>>food>>score;
        v[0] = lang; v[1]=part; v[2]=car; v[3] = food;
       
        s="";
        for(int j=0; j<v.size(); j++){
            if(v[j]!="-") s+=v[j];
        }
        
        for(int j=0; j<infoMap[s].size(); j++){
            if(infoMap[s][j]>=score) answer[i]++;
        }
    }
    
    return answer;
}

istringstream을 추천받아서 사용했는데, 확실히 타입을 바로 변환해주니까 번거로운 게 줄었다.
또 효율성을 생각해서 문제를 푸는 게 정말 머리아프고 어렵지만 중요한 과정이라고 생각했다.
다른 풀이를 보니까 처음에 map에 조합을 짜는 것도 무지성으로 하는 게 아니라 재귀를 통해서 만들던데, 다음에 그 알고리즘도 한 번 보고 이해해봐야겠다.

시간도 많이 썼고 다른 사람 팁을 많이 참고하긴 했지만 무려 11점이나 오르길래 뿌듯했다.

2개의 댓글

comment-user-thumbnail
2022년 12월 26일

와 규빈아 일단 문제 푼거 잘했긴 했는데 내 의도와는 다른 저 문제 풀이에 너무 놀랐다....떄려맞추기 진짜 잘한다 ㅋㅋㅋㅋㅋ

1개의 답글