[ 백준 ] 1713 / 후보 추천하기

金弘均·2021년 9월 15일
0

Baekjoon Online Judge

목록 보기
95/228
post-thumbnail

# Appreciation

/*
 * Problem :: 1713 / 후보 추천하기
 *
 * Kind :: Simulation
 *
 * Insight
 * - 다음과 같은 정보를 항상 알고 있어야 한다
 *   + 사진틀에 올라간 학생들의 번호
 *   + 사진틀에 올라간 학생들의 순서
 *   + 사진틀에 올라간 학생들의 추천받은 횟수
 *   # Frame 이라는 구조체를 정의하고 (vector<Frame>) F 를 선언해서
 *     현재 사진틀에 올라간 학생들의 정보를 추적하자
 *
 * Point
 * - 근데 위의 F 에서 번호가 10 인 학생을 어떻게 찾지?
 *   + for 문을 써서 찾을 수 있지만... 폼이 안난다
 *     뭔가 <alogirhtm> 에서 find 를 잘 활용하면 될 것 같은데...
 *     # predicate 를 활용하자!
 *   + 현재까지 추천 받은 횟수가 가장 적고 가장 오래된 학생도
 *     <algorithm> 에서 min_element 를 잘 활용하면 될 것 같은데...
 *     # < 연산자 오버로딩을 활용하자!
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define endl '\n'

// Set up : Global Variables
struct Frame { int no, ord, likes; };

// Set up : Functions Declaration
bool operator < (Frame u, Frame v);


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    int N; cin >> N;
    int M; cin >> M;
    int R[M];
    for (int i=0; i<M; i++)
        cin >> R[i];

    // Process
    vector<Frame> F; /* 현재 사진틀에 올라간 학생들의 정보 <= 정렬되어있지는 않음
                      * 사진틀은 학생의 번호, 게시된 순서, 추천받은 횟수를 정보로 가지고 있음 */
    for (int i=0; i<M; i++) {
        int no = R[i]; /* 현재 추천받은 학생의 번호 */
        /* 추천받은 학생의 번호와 같은 번호를 가진 사진틀의 인덱스(이터레이터)를 반환 */
        auto p = find_if(F.begin(), F.end(), [no](Frame f) {
            return f.no == no;
        });
        if (p != F.end()) { /* 추천받은 학생과 같은 번호를 가진 사진틀이 있다면 */
            p->likes++; /* 그 학생의 추천받은 횟수 증가 */
        } else { /* 추천받은 학생과 같은 번호를 가진 사진틀이 없다면 */
            if (F.size() == N) { /* 현재 비어있는 사진틀이 없다면 */
                /* 현재까지 추천받은 횟수가 가장 적고 가장 오래된 사진틀을 제거 */
                F.erase(min_element(F.begin(), F.end()));
            }
            /* 새로운 사진틀 추가 */
            F.push_back({no, i, 1});
        }
    }

    /* 현재 사진틀에 있는 학생들의 번호가 오름차순이 되도록 정렬 */
    sort(F.begin(), F.end(),
         [](Frame u, Frame v) {
        return u.no < v.no;
    });

    // Control : Output
    for (Frame f : F) {
        cout << f.no << ' ';
    }
}

// Helper Functions
bool operator < (Frame u, Frame v)
/* Fraem 구조체 비교를 위한 연산자(<) 오버로딩 */
{
    return make_pair(u.likes, u.ord) < make_pair(v.likes, v.ord);
}
profile
이런 미친 게임을 봤나! - 옥냥이

0개의 댓글