알고리즘

수강신청

게르마늄팔찌전도사 2024. 11. 15. 15:17

문제

국민대학교에서는 매 학기 시작 전 종합정보시스템에서 수강신청을 한다. 매 수강신청마다 아주 많은 학생들이 몰려 서버에 많은 부하가 가기 때문에, 국민대학교에서는 수강신청 부하 관리 시스템을 도입하기로 결정하였다. 새로운 관리 시스템은 다음과 같은 방식으로 동작한다.

  1. 수강신청 버튼이 활성화 된 후, 수강신청 버튼을 조금이라도 빨리 누른 학생이 대기목록에 먼저 들어간다.
  2. 이미 대기열에 들어가 있는 상태에서 다시 수강신청 버튼을 누를 경우 대기목록의 맨 뒤로 밀려난다.
  3. 잠시 후 수강신청 버튼이 비활성화 되면, 대기목록에서 가장 앞에 있는 학생부터 자동으로 수강신청이 완료되며, 수강 가능 인원이 꽉 찰 경우 나머지 대기목록은 무시하고 수강신청을 종료한다.

위의 표는 최대 수강 가능 인원이 3명인 알고리즘 수업에 대해 6명의 학생이 수강신청을 진행한 모습이다. 버튼이 비활성화 된 후, 먼저 규칙 1을 적용하여 클릭을 2번 이상 한 학생의 중복된 대기목록을 삭제한다. 중복된 목록을 제거한 후, 맨 앞에서부터 최대 수강 가능 인원인 3명을 선정한다. 표의 맨 오른쪽에는 그 최종결과를 나타낸 모습이다. 이와 같은 방법을 이용하여 최종적으로 수강신청에 성공한 인원을 출력하는 프로그램을 작성하시오.

입력

입력 데이터는 표준 입력을 사용한다. 입력은 1개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 과목의 수강 가능 인원 K(1 ≤ K ≤ 100,000)와 학생들이 버튼을 클릭한 순서를 기록한 대기목록의 길이 L(1 ≤ L ≤ 500,000)이 주어진다. 두 번째 줄부터 L개의 줄에는 수강신청을 버튼을 클릭한 학생의 학번이 클릭 순서대로 주어진다. 학번은 8자리의 숫자로 이루어져 있다.

출력

출력은 표준 출력을 사용한다. 입력받은 데이터에 대해, 수강신청 관리 시스템의 규칙을 적용한 후 수강신청에 성공한 인원의 학번을 한 줄에 1개씩 출력한다.

예제 입력 1

3 8
20103324
20133221
20133221
20093778
20140101
01234567
20093778
20103325

예제 출력 1

20103324
20133221
20140101

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
 
using namespace std;
 
bool compare(const pair<stringint>& a, const pair<stringint>& b) {
    return a.second < b.second;
}
 
int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
 
    int k, l;
    cin >> k >> l;
 
    unordered_map<stringint> student;
    for (int i = 0; i < l; i++) {
        string number;
        cin >> number;
        student[number] = i;
    }
 
    vector<pair<stringint>> v;
    for (auto& i : student)
        v.push_back(i);
 
    sort(v.begin(), v.end(), compare);
 
    for (int i = 0; i < min(k, (int)v.size()); i++)
        cout << v[i].first << '\n';
 
    return 0;
}
cs

 

계속 오답  끝에 답지를 본 문제다. 왜 계속 풀지 못했냐면 계속 queue를 사용해야겠다는 생각에 사로잡혀 시간초과가 나버렸다. queue를 이용하면 쉽고 빠르게 풀 수 있을 거라고 생각했는데 전혀 아니었다. l번의 학생 데이터를 입력받을 때  O(n)이 소요 vector에 데이터를 옮기고 정렬하는 데 O(nlogn)시간이 소요되고,  k명의 학생을 출력하는 데 O(k) 시간이 소요된다. sort를 이용해 정렬하는데는 O(nlogn)이 필요하다. 고로 이 문제는 O(nlogn)으로 풀 수 있는 문제였다. 

 

compare을 이용하여 클릭 순서대로 정렬하고 출력하면 된다. 

 

'알고리즘' 카테고리의 다른 글

연결 요소의 개수  (0) 2024.11.27
DFS와 BFS  (0) 2024.11.27
대칭 차집합  (1) 2024.11.14
숫자 카드 2  (0) 2024.11.11
베스트셀러  (0) 2024.11.07