본문 바로가기
알고리즘 문제풀이 입문: 코딩테스트 대비/섹션 5. Stack, Queue(자료구조)

응급실

by _비니_ 2024. 4. 15.

설명

메디컬 병원 응급실에는 의사가 한 명밖에 없습니다.

응급실은 환자가 도착한 순서대로 진료를 합니다. 하지만 위험도가 높은 환자는 빨리 응급조치를 의사가 해야 합니다.

이런 문제를 보완하기 위해 응급실은 다음과 같은 방법으로 환자의 진료순서를 정합니다.

• 환자가 접수한 순서대로의 목록에서 제일 앞에 있는 환자목록을 꺼냅니다.

• 나머지 대기 목록에서 꺼낸 환자 보다 위험도가 높은 환자가 존재하면 대기목록 제일 뒤로 다시 넣습니다. 그렇지 않으면 진료를 받습니다.

즉 대기목록에 자기 보다 위험도가 높은 환자가 없을 때 자신이 진료를 받는 구조입니다.

현재 N명의 환자가 대기목록에 있습니다.

N명의 대기목록 순서의 환자 위험도가 주어지면, 대기목록상의 M번째 환자는 몇 번째로 진료를 받는지 출력하는 프로그램을 작성하세요.

대기목록상의 M번째는 대기목록의 제일 처음 환자를 0번째로 간주하여 표현한 것입니다.

 

입력

첫 줄에 자연수 N(5<=N<=100)과 M(0<=M<N) 주어집니다.

두 번째 줄에 접수한 순서대로 환자의 위험도(50<=위험도<=100)가 주어집니다.

위험도는 값이 높을 수록 더 위험하다는 뜻입니다. 같은 값의 위험도가 존재할 수 있습니다.

 

출력

M번째 환자의 몇 번째로 진료받는지 출력하세요.

 

예시 입력 1 

5 2
60 50 70 80 90

 

예시 출력 1

3

 

 

문제 해결

 

조굼 어려웠담,, 도착 순서대로 진료를 보지만, 대기 목록에 자신보다 위험도가 높은 환자가 있으면 대기 목록의 맨 끝으로 가게 되는 문제이고, 특정 도착 순서의 환자가 몇 번째로 진료를 받았는지 출력하는 문제이다.

 

우선 위험도와 도착 순서가 다르므로 정수 배열을 요소로 하는 큐를 선언한다. 사실 이렇게 할 수 있는지 몰라서 문제 푸는데 좀 오래 걸렸다. 머리로 생각하는 게 코드로 나오지 못 했담.

Queue<int[]> patientsQueue = new LinkedList<>();

 

 

 

PatientArr[i]의 정수값, 즉 위험도와 / i (i를 순서대로 돌며 넣으므로 즉 도착 순서를 의미) 를 요소로 가지는 배열을 patientQueue에 넣는다.

for (int i = 0; i < N; i++) {
    patientsQueue.offer(new int[]{Integer.valueOf(PatientsArr[i]), i}); // {위험도, 순서}
}

 

 

진료 순서를 저장할 order 변수를 초기화해주고, 큐가 비어있지 않을 동안 반복해야하므로 while문을 만들어준다.

큐에서 꺼내온 값을 currentPatient 라고 해주었다.

그리고 응급상황인 경우와 아닌 경우를 구분해주어야 하므로 boolean 형으로 isEmergency 변수도 만들어주었당

int order = 0;
while (!patientsQueue.isEmpty()) {
    int[] currentPatient = patientsQueue.poll();

    boolean isEmergency = true; //제일 응급 환자인 경우 true

 

 

큐에서 환자를 한 명씩 꺼내며 0번째 인덱스, 즉 위험도를 비교한다. 현재 환자의 위험도가 더 낮으면 isEmergency를 false로 바꿔주고 나간다. (초기값은 true)

for (int[] patient : patientsQueue) {
    if (currentPatient[0] < patient[0]) {
        isEmergency = false;
        break;
    }
}

 

만약 응급 환자인 경우 order를 하나 올려주고, 이는 진료 순서가 될 것이다.

이 때 currentPatient 배열의 1번째 요소, 즉 도착 순서가 문제에서 원하는 순서 (M) 일 때의 order를 출력해주고 빠져나가면 된다. 

만약 제일 응급이 아닌 경우, 현재 환자를 큐의 맨 뒤로 다시 삽입해주면 된당

 

 

최종 코드

 

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class P08_응급실 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int M = in.nextInt();
        in.nextLine();
        String patients = in.nextLine();
        String[] PatientsArr = patients.split(" ");

        Queue<int[]> patientsQueue = new LinkedList<>();

        for (int i = 0; i < N; i++) {
            patientsQueue.offer(new int[]{Integer.valueOf(PatientsArr[i]), i}); // {위험도, 순서}
        }

        int order = 0;
        while (!patientsQueue.isEmpty()) {
            int[] currentPatient = patientsQueue.poll();

            boolean isEmergency = true; //제일 응급 환자인 경우 true
            for (int[] patient : patientsQueue) {
                if (currentPatient[0] < patient[0]) {
                    isEmergency = false;
                    break;
                }
            }
            if (isEmergency) { //제일 응급 환자인 경우
                order++; //진료 순서+ (order번째)
                if(currentPatient[1] == M){
                    System.out.println(order);
                    break;
                }
            }
            else //아닌 경우
                patientsQueue.offer(currentPatient); //다시 큐의 맨 뒤로 삽입
        }
    }
}
반응형