본문 바로가기
코딩/문제풀이-백준

백준 1700번 - 멀티탭 스케줄링 (C++)

by 남대현 2021. 9. 17.
반응형

문제

해결 방법

그리디 알고리즘을 사용하며 현재 멀티탭에 꽂혀 있는 용품 중, 이후에 등장하지 않는것을 뽑고, 이후에 등장하지 않는 용품이 없다면 그중 가장 나중에 사용하는 것 순서로 제거하면 된다. 이를 위하여 입력 시, 벡터에 용품들이 사용되는 순서에 대하여 2차원 배열 형태로 추가로 저장하였다.

아쉬웠던 점

골드 1이라 기대했는데 너무 쉬웠다. 특히 문제의 범위가 너무 좁아 삭제가 들어간 내 코드도 0ms가 나와서 상위권의 좋은 코드들을 보지 못하는 것도 단점이라고 생각한다.

코드

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <vector>
#include <set>
using namespace std;
 
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    int Num, Using_Num, Ans = 0;
    cin >> Num >> Using_Num;
    set<int> Tap; //멀티탭
    vector<int> Using_Vec(Using_Num); //전기용품 사용 순서
    vector<vector<int>> Using_Timing(101); //해당 용품이 언제 사용되는지 모두 저장.
    for (int i = 0; i < Using_Num; ++i)
    {
        cin >> Using_Vec[i];
        Using_Timing[Using_Vec[i]].emplace_back(i);
    }
 
    for (int i = 0; i < Using_Num; ++i)
    {
        //멀티탭 꽉 차고, 넣으려는 숫자가 탭에 없을 때 = 하나 뽑고 넣어야 할 때.
        if (Tap.size() == Num && Tap.count(Using_Vec[i]) == 0
        {
            int a = 0, b = 0;
            for (set<int>::iterator iter = Tap.begin(); iter != Tap.end(); iter++)
            {
                //앞으로 안나오는거 우선 제거.
                if (Using_Timing[*iter].empty())
                {
                    b = *iter;
                    break;
                }
                //이후에 늦게 나오는거 대상으로 지정.
                else if (Using_Timing[*iter].front() > i)
                {
                    if (a < Using_Timing[*iter].front())
                    {
                        a = Using_Timing[*iter].front();
                        b = *iter;
                    }
                }
            }
            
            //대상 삭제
            Tap.erase(Tap.find(b));
            Ans++;
        }
 
        //멀티탭에 현재 사용 용품 추가. set사용하여서 중복일 경우 무시됨.
        Tap.insert(Using_Vec[i]);
        //용품 사용 기록에서 현재 사용을 제거.
        Using_Timing[Using_Vec[i]].erase(Using_Timing[Using_Vec[i]].begin());
    }
    cout << Ans;
}
cs

삭제를 사용하지 않고 해결하려면 매번 뒤에서부터 현재 위치까지 순회하며 가장 순서가 나중인것/혹은 나오지 않는것을 찾아 대상을 삭제 해야할 것 같은데 그보다는 쿨하게 삭제하며 진행하는게 더 깔끔할 것 같았다.

 

잡설 : 잠이 안와서 간만에 주석좀 이쁘게 달았다 ㅋㅋ 그리고 이게 어떻게 골드 1이지....????

반응형

'코딩 > 문제풀이-백준' 카테고리의 다른 글

백준 11438번 - LCA2 (C++)  (0) 2021.10.02
백준 5430번 - AC (C++)  (0) 2021.10.02
백준 19237번 - 어른 상어 (C++)  (1) 2021.08.20
백준 1430번 - 공격 (C++)  (0) 2021.08.07
백준 2206번 - 벽 부수고 이동하기 (C++)  (0) 2021.07.30

댓글