[SW Expert] [모의 SW 역량테스트] 2447번 차량 정비소
Algorithm/SW Expert Academy

[SW Expert] [모의 SW 역량테스트] 2447번 차량 정비소

728x90

SW Expert [모의 SW 역량테스트] 2447번 차량 정비소 :

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV6c6bgaIuoDFAXy

 

역대급 요구사항이 많은 문제였다...

요구사항이 많다 보니 정리하는 것이 쉽지 않았다.

 

초기에 t = 0으로 선언한 뒤, while문 안에서 t를 1씩 증가시키며 시간의 흐름을 표현한다.

고객의 도착시간과 t가 일치한다면 reception Queue에 추가한다.

이는 고객이 방문하여 접수 창구 전에 기다리는 것을 나타낸다.

 

접수 창구와 정비 창구는 Desk라는 클래스를 선언하여 상태와 시간 등의 변수를 조작했다.

Desk 클래스에는 clear, next, in 함수가 포함되어 있다.

in 함수는 창구에 사람이 도착했을 때 호출된다.

매개변수 client을 입력받아 해당 창구에서 일을 보는 사람의 번호를 저장한다.

또한 창구에 사람이 있다면 다른 사람을 받을 수 없으므로 상태(status)를 false로 변환한다.

next 함수는 창구에 사람이 있다면 매시간 호출된다.

temp라는 임시 변수를 1씩 증가시키며 time과 일치한다면 상태를 true로 변환한다.

clear 함수는 일을 보던 사람이 나갔을 경우 호출된다.

모든 변수 값을 초기화해주는 함수이다.

 

전체적인 흐름으로는,

1. 해당 시간에 정비소에 들른 사람이 있다면 reception Queue에 추가한다.

2. 접수 창구를 for문으로 탐색한다.

   2-1. status가 true면서 client가 0이 아니면 접수를 마쳤다는 뜻이므로 repair Queue에 넣는다.

   2-2. status가 true인 곳에 Queue에서 하나 꺼내어 넣는다. (in 함수)

   2-3. status가 false인 곳의 temp 값을 하나 증가하여 시간이 지남을 표시한다. (next 함수)

3. 정비 창구를 for문으로 탐색하며 2번의 접수 창구에서 했던 로직을 반복한다.

 

문제의 길이가 너무 길어 이해하는 데도 오래 걸리고, 변수들도 많아서 처리해야 할 것들이 많았던 문제이다.

문제를 이해하고 코드를 본격적으로 작성하기까지 30분정도는 소모한 듯 하다.

 

 

총 걸린 시간 : 1시간 30분

난이도 : ★★★★☆

 

코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    private static int n, m, k, a, b;
    private static Desk[] ai, bj;
    private static int[] tk;
    private static int[][] visit;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int T = Integer.parseInt(br.readLine());

        for (int t = 1; t <= T; t++) {
            int temp;
            st = new StringTokenizer(br.readLine());

            n = Integer.parseInt(st.nextToken());
            m = Integer.parseInt(st.nextToken());
            k = Integer.parseInt(st.nextToken());
            a = Integer.parseInt(st.nextToken());
            b = Integer.parseInt(st.nextToken());

            ai = new Desk[n];
            bj = new Desk[m];
            tk = new int[k];
            visit = new int[k + 1][2];

            st = new StringTokenizer(br.readLine());
            for (int i = 0; i < n; i++) {
                temp = Integer.parseInt(st.nextToken());
                ai[i] = new Desk(temp);
            }
            st = new StringTokenizer(br.readLine());
            for (int i = 0; i < m; i++) {
                temp = Integer.parseInt(st.nextToken());
                bj[i] = new Desk(temp);
            }
            st = new StringTokenizer(br.readLine());
            for (int i = 0; i < k; i++) {
                tk[i] = Integer.parseInt(st.nextToken());
            }

            System.out.println("#" + t + " " + solution());
        }
    }

    private static int solution() {
        int t = 0, answer = 0, num, count = 0, index = 0;
        Queue<Integer> reception = new LinkedList<>();
        Queue<Integer> repair = new LinkedList<>();

        while (count != k) { // count는 정비 창구에 도착한 사람의 수
            for (int i = index; i < k; i++) { // waiting
                if (tk[i] == t) {
                    reception.add(i + 1);
                    index = i + 1;
                } else break;
            }
            for (int i = 0; i < n; i++) { // 접수 창구에 배치
                if (ai[i].status && ai[i].client != 0) {
                    repair.add(ai[i].client); // 수리 창구 waiting에 추가
                    ai[i].clear(); // 빠져나감
                }
                if (!reception.isEmpty()) {
                    if (ai[i].status) {
                        num = reception.poll();
                        visit[num][0] = i + 1;
                        ai[i].in(num);
                    }
                }
                if (!ai[i].status) ai[i].next();
            }

            for (int i = 0; i < m; i++) { // 정비 창구에 배치
                if (bj[i].status && bj[i].client != 0) {
                    bj[i].clear();
                }
                if (!repair.isEmpty()) { 
                    if (bj[i].status) { // 정비 창구에 입장
                        num = repair.poll();
                        visit[num][1] = i + 1;
                        count++;
                        if (visit[num][0] == a && visit[num][1] == b) answer += num;
                        bj[i].in(num);
                    }
                }
                if (!bj[i].status) bj[i].next();
            }
            t++;
        }
        return (answer == 0) ? -1 : answer;
    }
}


class Desk {
    int time, temp, client;
    boolean status;

    public Desk(int time) {
        this.time = time;
        this.temp = 0;
        this.client = 0;
        this.status = true;
    }

    public void clear() {
        this.client = 0;
        this.temp = 0;
        this.status = true;
    }

    public void next() {
        temp++;
        if (temp == time) this.status = true;
    }

    public void in(int client) {
        this.client = client;
        this.status = false;
    }
}
728x90