본문 바로가기
삼성 코팅테스트 준비/모의 역량 테스트 문제

2477 차량 정비소

by tryotto 2020. 3. 4.
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include <stdio.h>
#include <string.h>
#include <deque>
#include <vector>
 
using namespace std;
 
int num_account, num_repair, num_customer, find_acc, find_rep;
int time_acc[30], time_rep[30], time_arrive[1001];
int cur_acc[30], cur_rep[30];
int time_left_acc[30], time_left_rep[30];
int cur_acc_num, cur_rep_num;
int left_customer;
int dead = 1000000000;
deque<int> wait_list;
deque<int> wait_list2;
vector<vector<int> > record_acc;
vector<vector<int> > record_rep;
 
void new_testcase();
void time_pass(int time);
void accounting();
void repairing();
int find_customer(int idx1, int idx2);
int ending();
 
int main() {
    int test;
    scanf("%d"&test);
 
    for (int t = 1; t <= test; t++) {
        new_testcase();
 
        for (int i = 0; ; i++) {
            time_pass(i);
            accounting();
            repairing();
 
            if (ending()) {
                break;
            }
        }
        int num = find_customer(find_acc, find_rep);
        printf("#%d %d\n", t, num);
    }
}
 
int find_customer(int idx1, int idx2) {
    int rst_v = 0;
    vector<int> tmp_customer(num_customer + 10);
    for (int i = 0; i < record_acc[idx1].size(); i++) {
        int cust = record_acc[idx1][i];
        tmp_customer[cust]++;
    }
    for (int i = 0; i < record_rep[idx2].size(); i++) {
        int cust = record_rep[idx2][i];
        tmp_customer[cust]++;
    }
 
    for (int i = 1; i <= num_customer; i++) {
        if (tmp_customer[i] > 1) {
            rst_v += i;
        }
    }
    if (rst_v > 0)
        return rst_v;
    else
        return -1;
}
 
int ending() {
    if (wait_list.size() > 0 || wait_list2.size() > 0)
        return 0;
    if (cur_acc_num > 0 || cur_rep_num > 0)
        return 0;
    if (left_customer > 0)
        return 0;
    return 1;
}
 
void time_pass(int time) {
    // waiting acc 생성
    for (int i = 1; i <= num_customer; i++)
        if (time >= time_arrive[i] && time_arrive[i] != dead) {
            wait_list.push_back(i);
            time_arrive[i] = dead;
            left_customer--;
        }
 
    // account 갱신 + waiting_rep 생성
    for (int i = 1; i <= num_account; i++) {
        if (time_left_acc[i] > 0) {
            time_left_acc[i]--;
 
            if (time_left_acc[i] == 0) {
                int tmp = record_acc[i].back();
                wait_list2.push_back(tmp);
 
                cur_acc[i] = 0;
                cur_acc_num--;
            }
        }
    }
 
    // repair 갱신
    for (int i = 1; i <= num_repair; i++) {
        if (time_left_rep[i] > 0) {
            time_left_rep[i]--;
 
            if (time_left_rep[i] == 0) {
                cur_rep[i] = 0;
                cur_rep_num--;
            }
        }
    }
}
 
void accounting() {
    if (wait_list.size() == 0)
        return;
 
    // waiting -> accounting 흐름
    while ((cur_acc_num < num_account) && (wait_list.size() > 0)) {
        for (int i = 1; i <= num_account; i++) {
            if (cur_acc[i] == 0) {
                int tmp = wait_list.front();
                wait_list.pop_front();
                record_acc[i].push_back(tmp);
 
                cur_acc[i] = 1;
                time_left_acc[i] = time_acc[i];
                cur_acc_num++;
            }
 
            if (wait_list.size() <= 0)
                break;
        }
    }
}
 
void repairing() {
    if (wait_list2.size() == 0)
        return;
 
    // waiting2 -> repairing 흐름
    while ((cur_rep_num < num_repair) && (wait_list2.size() > 0)) {
        for (int i = 1; i <= num_repair; i++) {
            if (cur_rep[i] == 0) {
                int tmp = wait_list2.front();
                wait_list2.pop_front();
                record_rep[i].push_back(tmp);
 
                cur_rep[i] = 1;
                time_left_rep[i] = time_rep[i];
                cur_rep_num++;
            }
 
            if (wait_list2.size() <= 0)
                break;
        }
    }
}
 
void new_testcase() {
    // vector
    record_acc.assign(30vector<int>());
    record_rep.assign(30vector<int>());
 
    // memset
    memset(time_acc, 0sizeof(time_acc));
    memset(time_rep, 0sizeof(time_rep));
    memset(time_arrive, 0sizeof(time_arrive));
    memset(cur_acc, 0sizeof(cur_acc));
    memset(cur_rep, 0sizeof(cur_rep));
    memset(time_left_rep, 0sizeof(time_left_rep));
    memset(time_left_acc, 0sizeof(time_left_acc));
 
    // deque
    while (!wait_list.empty())
        wait_list.pop_back();
    while (!wait_list2.empty())
        wait_list2.pop_back();
 
    // variables
    cur_acc_num = 0;
    cur_rep_num = 0;
 
    // scanf
    scanf("%d %d %d %d %d"&num_account, &num_repair,
        &num_customer, &find_acc, &find_rep);
    left_customer = num_customer;
    for (int i = 1; i <= num_account; i++)
        scanf("%d"&time_acc[i]);
    for (int i = 1; i <= num_repair; i++)
        scanf("%d"&time_rep[i]);
    for (int i = 1; i <= num_customer; i++)
        scanf("%d"&time_arrive[i]);
}
 
cs

체감상 정말 생각할게 많았던 문제였다
코드 길이만 봐도 200줄 가까이 되네

그래도 뭐 dfs 같은 알고리즘이 전혀 필요 없고,
그냥 덱이랑 벡터를 적절하게 사용할 줄 알면 됐다
거기에다가 중간중간에 세밀한 사고 과정이 필요해서 애를 좀 먹었다


'삼성 코팅테스트 준비 > 모의 역량 테스트 문제' 카테고리의 다른 글

4014 활주로 건설  (0) 2020.03.04
1953 탈주범 검거  (0) 2020.03.04
2105 디저트 카페  (0) 2020.03.03
2115 벌꿀채취  (0) 2020.03.03
4012 요리사  (0) 2020.03.03