-
2477.차량 정비소알고리즘/SW Expert Academy 2020. 7. 7. 23:56
오랜만에 문제를 풀었다. 그 동안 했던 것 중에 잘 모르겠던거 복습도하고 충분한 휴식도 취하고 왔다. 이제 다시 달려야지!!
이번에 풀어볼 문제는 SW Expert의 2477번 문제 차량 정비소이다.
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
생각보다 굉장히 까다로운 시뮬레이션이고 이 문제는 설계를 망치면 그냥 꼬여버리는 문제이다.
설계만 잘한다면 난이도는 그리 높지 않다. 그럼에도 1시간 29분 정도 걸렸다. 너무 헷갈려..ㅠ
이 문제를 푸는 포인트는 생각해보면 굉장히 간단하다.
1. 대기열을 생각해줘야한다.
=> 바로 고객이 도착해서 접수 창구로 가는 사이에 waiting하는 대기열
=> 접수창구에서 정비창구로가는 waiting 대기열을 생각해주고 설계히면 된다.
2. 둘다 들리는 경우를 체크해주면된다.
=> 배열을 하나 선언해서 A와 B 창구를 들린 고객번호의 index의 값 더해 2가 나오면 둘 다 거쳐간 것으로 체크하였다.
< Code 설명 >
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
#pragma warning(disable:4996)#include <iostream>#include <deque>#include <string.h>#define MAX 1001using namespace std;int T, N, M, K, A, B;int answer[MAX]; // 접수창구와 정비창구를 거쳤는지 판별하는 배열deque<pair<int, int>>cus; // 고객정보 : 고객번호, 걸린시간deque<int>wait1; // 대기 큐 ( 도착에서 접수창구 )deque<int>wait2; // 대기 큐 ( 접수창구에서 정비창구 )deque<pair<int,int>>box1; // 고객번호, 소요 시간 => 고객번호가 0이면 고객을 받음 소요시간이 0이면 두 번째 대기큐로 보냄deque<pair<int,int>>box2; // 고객번호, 소요 시간deque<int> box1_save; // 접수창구 소요시간 저장deque<int> box2_save; // 정비창구 소요시간 저장int ans; // 접수창구와 정비창구를 거친 고객번호 : 정답void search(){int cnt = 0;while (true){if (cnt == K) // 고객 수가 전부다 업무가 끝나면break;// 종료for (int i = 0; i < (int)cus.size(); i++){ // 고객이 도착한 경우 대기 큐에 저장if (cus.front().second == 0){ // 고객이 도착한경우wait1.push_back(cus.front().first); // 해당 고객을 첫 번째 대기큐에 저장if (!cus.empty()){ // 고객정보가 비어있지 않았다면cus.pop_front(); // 도착한 고객정보 제거i = -1; // 제거 후에는 다시 제일 처음부터 탐색함 ( 도착한 고객이 또 있을 수 있으니 )}}}for (int i = 0; i < N; i++){ // 접수 창구 수만큼 탐색if (box1[i].second == 0){ // 접수창구 소요시간이 다지나면box1[i].second = box1_save[i]; // 접수창수 소요시간 다시 초기화if (i + 1 == A) // 우리가 찾는 창구를 이용한 고객이라면answer[box1[i].first] += 1; // 방문 고객 idx값 +1wait2.push_back(box1[i].first); // 접수창고에서 업무 다봤으니 두 번째 대기큐에 저장box1[i].first = 0; // 대기 큐로 보냈으니 접수창구에서는 이용고객 제거}if (box1[i].first == 0 && !wait1.empty()){ // 접수창구가 비어있으면box1[i].first = wait1.front(); // 접수창구에 대기 큐 제일 앞의 값을 저장if (!wait1.empty())wait1.pop_front(); // 대기 큐의 제일 앞은 삭제}if (box1[i].first) // 접수창구에 고객이 있으면box1[i].second -= 1; // 소요시간 -1}for (int i = 0; i < M; i++){ // 정비 창구의 수만큼 탐색if (box2[i].second == 0){ // 정비창구 소요시간이 다지나면box2[i].second = box2_save[i]; // 정비창수 소요시간 다시 초기화if (i + 1 == B && answer[box2[i].first]==1) // 이전에 A창구를 들렸으면서 B창구를 들린 고객이라면answer[box2[i].first] += 1; // 방문 고객 idx값 +1box2[i].first = 0; // 접수창구 이용고객 제거cnt += 1; // 고객한명이 완전히 업무를 마치고 나갔으므로 +1}if (box2[i].first == 0 && !wait2.empty()){ // 정비창구가 비어있으면box2[i].first = wait2.front(); // 정비창구에 대기 큐 제일 앞의 값을 저장wait2.pop_front(); // 대기 큐의 제일 앞은 삭제}if (box2[i].first) // 정비창구에 고객이 있으면box2[i].second -= 1; // 소요시간 -1}for (int i = 0; i < (int)cus.size(); i++) // 시간이 지났으므로cus[i].second -= 1; // 고객 도착시간 - 1}for (int i = 1; i <= K; i++){ // A와 B 창구를 거친 고객 idx는 2가 되어있으므로if (answer[i]==2) // 결과가 2인 배열값만 더해줌ans += i;}}void init(){ // 초기화memset(answer, 0, sizeof(answer));ans = 0;cus.clear();wait1.clear();wait2.clear();box1.clear();box2.clear();box1_save.clear();box2_save.clear();}int main() {freopen("2477.txt", "r", stdin);cin >> T;for (int z = 1; z <= T; z++){init();cin >> N >> M >> K >> A >> B;int tmp;for (int i = 0; i < N; i++){cin >> tmp;box1.push_back(make_pair(0,tmp));box1_save.push_back(tmp);}for (int i = 0; i < M; i++){cin >> tmp;box2.push_back(make_pair(0,tmp));box2_save.push_back(tmp);}for (int i = 1; i <= K; i++){cin >> tmp;cus.push_back(make_pair(i, tmp));}search();if (ans == 0) // 더해지지 않았다는 것은 우리가 찾는 A,B를 모두 거친 고객이 없다는 것이므로cout << "#" << z << " " << -1 << "\n"; // -1을 출력elsecout << "#" << z << " " << ans << "\n";// 있다면 결과 출력}return 0;}cs 반응형'알고리즘 > SW Expert Academy' 카테고리의 다른 글
2382.미생물격리 (0) 2020.07.21 2383.점심 식사시간 (0) 2020.07.10 2105.디저트 카페 (0) 2020.06.27 2115.벌꿀채취 (0) 2020.06.23 4008.숫자 만들기 (0) 2020.06.19 댓글