본문 바로가기
Programming/Algorithm

swe 2477 차량 정비소

by OKOK 2018. 4. 13.

- 다른 알고리즘이 있는 것은 아니고,

- 얼마나 주어진 문장대로 구현을 잘하는지가 관건 입니다.

- 정비소, 들어가고 나오고, 대기 하는 곳이 있고, 이런것들을 잘 이해해야 합니다.

- 복잡한 것 같으나, 실제로 구현할면 시간이 그렇게 오래 걸리지 않습니다.

- 항상 정확하게 짜는 것에 중점을 둡니다.

- 초기화 조건 잘 확인하는 것이 필요합니다.


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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
1040 차량 정비소 시작
1시간 10분컷
구조체 잘 정리하고,
큐를 사용해서 처리하도록 합니다.
접수대 대기실 큐
정비실 대기방 큐
끝났을 때 저장하는 배열 하나.
지금 없는 자료구조가. 각 접수대 정비소에 들어간 사람과 들어간 시간을 저장하는 것입니다.
*/
 
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
 
int ans;
int N, M, K, A, B;
int recep_time[10];  // 접수대 걸리는 시간 저장
int repair_time[10]; // 정비소 걸리는 시간 저장
int arrive[1001]; // 처음 주어진 사람들이 접수대에 도착하는 시간
struct point {
    int num, t;
};
point recep[10]; // 들어가 있는 접수대 숫자, 들어간 사람의 숫자, 걸리는 시간 저장
point repair[10]; // 들어가 있는 정비대 숫자, 들어간 사람의 숫자, 걸리는 시간 저장
queue<int> rec_wait, rep_wait; // 대기소에 들어와 있는 사람들 번호
struct pInfo {
    int recN, repN;
};
pInfo person[1001]; // 사람이 거쳐간 곳을 저장합니다. 나중에 이결과를 토대로 정답 도출
int t;
int end_cnt;
 
void problemIn() {
    cin >> N >> M >> K >> A >> B;
    for (int i = 1; i <= N; i++) {
        cin >> recep_time[i];
    }
    for (int i = 1; i <= M; i++) {
        cin >> repair_time[i];
    }
    for (int i = 1; i <= K; i++) {
        cin >> arrive[i];
    }
}
 
void init() {
    ans = 0;
    t = 0;
    end_cnt = 0;
}
/*
도달하는 시간 -> 접수대 대기
접수대 끝난 사람 -> 정비실 대기에 넣기
정비실 끝난 사람 -> 끝난 사람 숫자 ++
접수대 대기 -> 접수대 비어 있으면 넣기.
정비실 대기 -> 정비실 비어 있으면 넣기.
모두 나왔는지 확인하기.
*/
 
void solve() {
    
    while (1) {
        
        //도달하는 시간이 현재시간과 동일하면 rec 대기에 넣어주기
        for (int i = 1; i <= K; i++) {
            if (arrive[i] == t) {
                rec_wait.push(i);
            }
        }
 
        //접수대 끝난 사람 -> 정비실 대기 넣기
        for (int i = 1; i <= N; i++) {
            if (recep[i].num != 0 && recep[i].t == t) {
                rep_wait.push(recep[i].num);
                recep[i].num = 0;
            }
        }
 
        //정비실 끝난 사람 -> 끝난 사람 숫자 ++
        for (int i = 1; i <= M; i++) {
            if (repair[i].num != 0 && repair[i].t == t) {
                repair[i].num = 0;
                end_cnt++;
            }
        }
 
        //접수대 대기 -> 접수대 비어 있으면 넣기
        for (int i = 1; i <= N; i++) {
            if (rec_wait.empty()) break;
            if (recep[i].num == 0) {
                recep[i].num = rec_wait.front();
                recep[i].t = t + recep_time[i]; //들어간시간 + 걸리는 시간
                rec_wait.pop();
                person[recep[i].num].recN = i; // 기록
            }
        }
 
 
        //정비실 대기 -> 정비실 비어 있으면 넣기
        for (int i = 1; i <= M; i++) {
            if (rep_wait.empty())break;
            if (repair[i].num == 0) {
                repair[i].num = rep_wait.front();
                repair[i].t = t + repair_time[i];
                rep_wait.pop();
                person[repair[i].num].repN = i;
            }
        }
 
        // 결과 확인
        if (K == end_cnt) {
            for (int i = 1; i <= K; i++) {
                if (person[i].recN == A && person[i].repN == B) {
                    ans += i;
                }
            }
            return;
        }
        t++;
    }
}
 
int main() {
    int T;
    cin >> T;
    for (int tc = 1; tc <= T; tc++) {
        problemIn();
        solve();
        if (ans == 0) ans = -1;
        cout << "#" << tc << " " << ans << endl;
        init();
    }
    return 0;
}
cs