코테 노트/SWEA

SWEA2477 [모의 SW 역량테스트] 차량 정비소 C++

화요밍 2021. 10. 19. 23:56
728x90
반응형

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV6c6bgaIuoDFAXy&categoryId=AV6c6bgaIuoDFAXy&categoryType=CODE&problemTitle=모의&orderBy=PASS_RATE&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=2 

 

최종 코드

 

GitHub - hwayeon351/SWEA-Algorithms: SWEA 알고리즘 소스 코드 모음

SWEA 알고리즘 소스 코드 모음. Contribute to hwayeon351/SWEA-Algorithms development by creating an account on GitHub.

github.com

//
//  main.cpp
//  SWEA2477_1
//
//  Created by Hwayeon on 2021/10/19.
//

#include <iostream>
#include <queue>
using namespace std;

int N, M;
int K;
int A, B;

struct Customer{
    int num;
    int recept_center;
    int repair_center;
    int recept_arrival_time;
    int repair_arrival_time;
};
struct Center{
    int time;
    int timer;
    Customer customer;
    bool check = false;
};
Customer customer;
struct recept_cmp{
    bool operator()(Customer c1, Customer c2){
        if(c1.recept_arrival_time == c2.recept_arrival_time)
            return c1.num > c2.num;
        return c1.recept_arrival_time > c2.recept_arrival_time;
    }
};
struct repair_cmp{
    bool operator()(Customer c1, Customer c2){
        if(c1.repair_arrival_time == c2.repair_arrival_time){
            return c1.recept_center > c2.recept_center;
        }
        return c1.repair_arrival_time > c2.repair_arrival_time;
    }
};
Center receptions[10];
Center repairs[10];

priority_queue<Customer, vector<Customer>, recept_cmp> recept_waitings;
priority_queue<Customer, vector<Customer>, repair_cmp> repair_waitings;

int answer = 0;

void operate_car_center(){
    int sec = 0;
    int done = 0;
    while(true){
        //1. 접수 처리
        for(int i=1; i<=N; i++){
            if(receptions[i].check){
                receptions[i].timer--;
                //접수 처리 종료
                if(receptions[i].timer == 0){
                    customer = receptions[i].customer;
                    customer.repair_arrival_time = sec;
                    repair_waitings.push(customer);
                    receptions[i].check = false;
                }
            }
        }
        //2. 정비 처리
        for(int j=1; j<=M; j++){
            if(repairs[j].check){
                repairs[j].timer--;
                //정비 처리 종료
                if(repairs[j].timer == 0){
                    customer = repairs[j].customer;
                    repairs[j].check = false;
                    done++;
                    if(customer.recept_center == A && customer.repair_center == B){
                        answer += customer.num;
                    }
                    if(done == K) return;
                }
            }
        }
        //2. 빈 접수 창구에 고객 배치
        for(int i=1; i<=N; i++){
            if(!receptions[i].check){
                if(recept_waitings.empty()) break;
                customer = recept_waitings.top();
                if(customer.recept_arrival_time > sec) break;
                recept_waitings.pop();
                customer.recept_center = i;
                receptions[i].check = true;
                receptions[i].customer = customer;
                receptions[i].timer = receptions[i].time;
            }
        }
        //3. 빈 정비 창구에 고객 배치
        for(int j=1; j<=M; j++){
            if(!repairs[j].check){
                if(repair_waitings.empty()) break;
                customer = repair_waitings.top();
                repair_waitings.pop();
                customer.repair_center = j;
                repairs[j].check = true;
                repairs[j].customer = customer;
                repairs[j].timer = repairs[j].time;
            }
        }
        sec++;
    }
}

int main(int argc, const char * argv[]) {
    int test_case;
    int T;
    cin >> T;
    for(test_case=1; test_case<=T; ++test_case){
        answer = 0;
        cin >> N >> M >> K >> A >> B;
        for(int i=1; i<=N; i++){
            cin >> receptions[i].time;
        }
        for(int j=1; j<=M; j++){
            cin >> repairs[j].time;
        }
        for(int k=1; k<=K; k++){
            customer.num = k;
            cin >> customer.recept_arrival_time;
            recept_waitings.push(customer);
        }
        operate_car_center();
        if(answer == 0) cout << "#" << test_case << " " << -1 << endl;
        else cout << "#" << test_case << " " << answer << endl;
    }
    return 0;
}

풀이 과정

풀이 시간 1시간 50분

#include <iostream>
#include <queue>
using namespace std;

int N, M;
int K;
int A, B;

struct Customer{
	//고객 번호
    int num;
    //이용한 접수 창구 번호
    int recept_center;
    //이용한 정비 창구 번호
    int repair_center;
    //접수 창구에 도착한 시간
    int recept_arrival_time;
    //정비 창구에 도착한 시간
    int repair_arrival_time;
};

struct Center{
	//창구 처리 시간
    int time;
    //이용 중인 고객이 있는 경우, 남은 처리 시간
    int timer;
    //이용 중인 고객
    Customer customer;
    //이용 중인 고객이 있으면 true, 없으면 false
    bool check = false;
};
Customer customer;

//접수 창구 우선순위 정렬
struct recept_cmp{
    bool operator()(Customer c1, Customer c2){
    	//접수 창구에 도착한 시간이 같은 경우,
        if(c1.recept_arrival_time == c2.recept_arrival_time)
        	//고객 번호가 작은 순서대로
            return c1.num > c2.num;
        //접수 창구에 도착한 시간이 빠른 순서대로
        return c1.recept_arrival_time > c2.recept_arrival_time;
    }
};

//정비 창구 우선순위 정렬
struct repair_cmp{
    bool operator()(Customer c1, Customer c2){
    	//정비 창구에 도착한 시간이 같은 경우,
        if(c1.repair_arrival_time == c2.repair_arrival_time){
        	//이용한 접수 창구 번호가 작은 순서대로
            return c1.recept_center > c2.recept_center;
        }
        //정비 창구에 도착한 시간이 빠른 순서대로
        return c1.repair_arrival_time > c2.repair_arrival_time;
    }
};

//접수 창구들을 나타내는 배열
Center receptions[10];
//정비 창구들을 나타내는 배열
Center repairs[10];

//접수 창구에 대기중인 고객
priority_queue<Customer, vector<Customer>, recept_cmp> recept_waitings;
//정비 창구에 대기중인 고객
priority_queue<Customer, vector<Customer>, repair_cmp> repair_waitings;

int answer = 0;

void operate_car_center(){
    int sec = 0;
    
    //차량 정비소 이용이 끝난 고객 수
    int done = 0;
    
    while(true){
        //1. 접수 처리
        for(int i=1; i<=N; i++){
        	//접수 창구를 이용 중인 고객이 있을 경우, 접수를 처리한다
            if(receptions[i].check){
                receptions[i].timer--;
                
                //접수 처리가 완료된 경우
                if(receptions[i].timer == 0){
                	//해당 고객을 정비 창구 대기줄에 세운다
                    customer = receptions[i].customer;
                    customer.repair_arrival_time = sec;
                    repair_waitings.push(customer);
                    
                    //해당 접수 창구의 상태를 false로 바꾼다
                    receptions[i].check = false;
                }
            }
        }
        
        //2. 정비 처리
        for(int j=1; j<=M; j++){
        	//정비 창구를 이용 중인 고객이 있을 경우, 정비를 처리한다
            if(repairs[j].check){
                repairs[j].timer--;
                
                //정비 처리가 완료된 경우
                if(repairs[j].timer == 0){
                	//해당 고객의 차량 정비소 이용이 끝났으므로 done 카운팅
                    customer = repairs[j].customer;
                    //해당 정비 창구의 상태를 false로 바꾼다
                    repairs[j].check = false;
                    done++;
                    
                    //지갑을 잃어버린 고객이 이용한 접수 창구, 정비 창구와 일치하는 경우, 해당 고객 번호를 더한다
                    if(customer.recept_center == A && customer.repair_center == B){
                        answer += customer.num;
                    }
                    //모든 고객이 차량 정비소를 모두 이용한 경우, 함수 종료
                    if(done == K) return;
                }
            }
        }
        
        //2. 빈 접수 창구에 고객 배치
        for(int i=1; i<=N; i++){
        	//현재 접수 창구가 비어 있는 경우,
            if(!receptions[i].check){
            	//접수 창구를 대기하는 고객이 없는 경우, for문을 빠져나간다
                if(recept_waitings.empty()) break;
                
                //접수 창구를 대기하는 고객이 있는 경우,
                customer = recept_waitings.top();
                if(customer.recept_arrival_time > sec) break;
                //대기줄에서 빠져나와 해당 접수 창구를 이용한다
                recept_waitings.pop();
                customer.recept_center = i;
                //접수 창구 상태 true로 변경
                receptions[i].check = true;
                receptions[i].customer = customer;
                //접수 처리 시간 타이머 가동
                receptions[i].timer = receptions[i].time;
            }
        }
        
        //3. 빈 정비 창구에 고객 배치
        for(int j=1; j<=M; j++){
        	//현재 정비 창구가 비어 있는 경우,
            if(!repairs[j].check){
            	//정비 창구를 대기하는 고객이 없는 경우, for문을 빠져나간다
                if(repair_waitings.empty()) break;
                
                //정비 창구를 대기하는 고객이 있는 경우, 대기줄에서 빠져나와 해당 정비 창구를 이용한다
                customer = repair_waitings.top();
                repair_waitings.pop();
                customer.repair_center = j;
                //정비 창구 상태를 true로 변경
                repairs[j].check = true;
                repairs[j].customer = customer;
                //정비 처리 시간 타이머 가동
                repairs[j].timer = repairs[j].time;
            }
        }
        sec++;
    }
}

int main(int argc, const char * argv[]) {
    int test_case;
    int T;
    cin >> T;
    for(test_case=1; test_case<=T; ++test_case){
        answer = 0;
        cin >> N >> M >> K >> A >> B;
        
        //각 접수 창구의 처리 시간을 설정 
        for(int i=1; i<=N; i++){
            cin >> receptions[i].time;
        }
        //각 정비 창구의 처리 시간을 설정
        for(int j=1; j<=M; j++){
            cin >> repairs[j].time;
        }
        //고객을 접수 창구 대기줄에 세운다
        for(int k=1; k<=K; k++){
            customer.num = k;
            cin >> customer.recept_arrival_time;
            recept_waitings.push(customer);
        }
        
        operate_car_center();
        
        if(answer == 0) cout << "#" << test_case << " " << -1 << endl;
        else cout << "#" << test_case << " " << answer << endl;
    }
    return 0;
}

 

728x90
반응형