-
[SWEA] 2477 차량 정비소문제 풀이 2020. 5. 6. 22:54
2477 차량 정비소
풀이)
처음에 잘못생각해서 틀렸던 문제이다.
시간을 1000초 까지만 고려해서 매 초마다 어떻게 변화하는지 확인했는데,
알고보니 1000초 까지만 고려하면 안됐다.
0<= tk <=1000이라는 것은, 손님이 0 초부터 1000초 중에 온다는 뜻이므로
1000초에 도착한 손님일 경우 접수창고 & 정비창고에 들어가는 시간은 1000초를 초과한다.
그래서 두번째로는 1000초동안 for문을 돌리는 것이 아니라,
while문으로 마지막 손님이 정비창구에 들어갈때 끝내줬다.
풀이과정을 말해보자면.
1초가 지날때마다
1. 접수창고의 처리 시간을 1씩 줄인다.
만약 접수창고 시간이 0이 되면 그 창고에 있던 고객이 접수를 끝냈다는 것이므로
정비창구에 갈 손님 vector에 넣어줬다.
2. 정비창고의 처리 시간을 1씩 줄인다.
3. 정비창구 들어갈 손님 vector가 비어있지 않다면,
vector를 손님이 온 시간, 손님의 접수 창구 번호로 정렬해줬다.
그리고 우선순위가 높은 손님을 정비 창구에 넣어줬다.
(이 때, 손님의 접수 창구와 정비 창구 번호를 둘 다 아니깐
a, b 값과 비교해서 둘 다 일치한다면 손님의 번호를 더해줬다.)
4. 손님이 현재 시간보다 전에 도착해서 기다리고 있고,
접수창고에 자리가 비었다면 손님을 넣어줬다.
위의 1,2,3,4번을 계속 반복하면 결과가 나온다.
말로 설명하자니,, 좀 어렵다.
그냥 문제에서 설명한 것을 요령없이 그대로 다 구현하면 되는 것이라서
귀찮고 오래걸릴뿐이지 어려운것은 아니다.
코드를 보면서 이해하는 것이 더 쉬울듯 하다.
코드)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126#include <stdio.h>#include <vector>#include <algorithm>#include <queue>#include <string.h>using namespace std;int n, m, k, a, b;int c_time[10];//접수창구 각 시간int r_time[10];//정비창구 각 시간int contact[10][2];//접수창구[창구번호],[남은 시간.고객번호]int repair[10];//정비창구[남은시간]struct re_customer {int time, connum, cusnum;//접수끝낸시간, 접수창고번호, 고객번호re_customer(int t,int o,int u) {this->time = t;this->connum = o;this->cusnum = u;}};//시간, 접수창구, 고객번호bool cmp( const re_customer &a, const re_customer &b) {if (a.time == b.time) {return a.connum < b.connum;}else {return a.time < b.time;}}int main() {//freopen("sample_input.txt", "r", stdin);int T = 0;scanf("%d", &T);for (int test_case = 1; test_case <= T; test_case++) {scanf("%d %d %d %d %d", &n, &m, &k, &a, &b);memset(c_time, 0, sizeof(c_time));memset(r_time, 0, sizeof(r_time));memset(contact, 0, sizeof(contact));memset(repair, 0, sizeof(repair));for (int i = 1; i <= n; i++) {scanf("%d", &c_time[i]);}for (int i = 1; i <= m; i++) {scanf("%d", &r_time[i]);}vector <pair<int, int>> customer;for (int i = 1; i <= k; i++) {int time = 0;scanf("%d", &time);customer.push_back({ time,i });}sort(customer.begin(), customer.end());//시간순으로 정렬int result = 0;int idx = 0;//고객의 인덱스vector <re_customer> vec;int cnt = 0;int t = customer[0].first;//각 시간별로확인while (cnt < k){//시간 감소for (int i = 1; i <= n; i++) {if (contact[i][0] > 0) contact[i][0]--;if (contact[i][0] == 0 && contact[i][1] != 0) {//고객이 접수창구에서 일을 다 끝냈으면vec.push_back({ t,i,contact[i][1] });contact[i][1] = 0;}}for (int i = 1; i <= m; i++) {if (repair[i] > 0) repair[i]--;}if (!vec.empty()) sort(vec.begin(), vec.end(), cmp);int full = 0;while (!vec.empty() && full < m) {//정비창구에 갈 손님이 있고, 다 차있지 않는다면full = 0;for (int i = 1; i <= m; i++) {//낮은 창구번호부터 확인if (repair[i] == 0) {//i번째 창구로 들어감repair[i] = r_time[i];//접수창고번호, 정비창고번호가 a,b랑 같다면if (vec[0].connum == a && i == b) {result += vec[0].cusnum;}vec.erase(vec.begin());cnt++;break;}else {full++;//차있음을 나타냄}}}full = 0;while (!customer.empty() && full < n){if (customer[0].first > t) break;full = 0;for (int i = 1; i <= n; i++) {//창구번호가 낮은 데부터 확인if (contact[i][0] == 0) {contact[i][0] = c_time[i];contact[i][1] = customer[0].second; // 손님번호customer.erase(customer.begin());break;}else {full++;}}}t++;}if (result == 0)printf("#%d -1\n", test_case);else printf("#%d %d\n", test_case, result);}return 0;}cs '문제 풀이' 카테고리의 다른 글
[SWEA] 1953 탈주범 검거 (0) 2020.05.08 [SWEA] 2382 미생물 격리 (0) 2020.05.07 [SWEA] 2112. 보호필름 (0) 2020.05.04 [SWEA]2105 디저트 까페 (0) 2020.05.01 [SWEA] 1949 등산로 조성 (0) 2020.04.29