알고리즘/알고리즘_swea

[Python][SWEA] 9280. 진용이네 주차타워 D3

Jerry_K 2024. 5. 12. 21:23
 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


 

🗒️ 파이썬 코드 풀이

from collections import deque
T = int(input())
for test_case in range(1, T + 1):
    n, m = list(map(int, input().split()))
    R_i = [int(input()) for _ in range(n)]
    W_i = [int(input()) for _ in range(m)]
    order_lst = [int(input()) for _ in range(m*2)]

    use_lst = [0] * n # 주차 사용가능 여부
    wait_lst = deque()  # 대기 차량 리스트
    sum = 0

    for o_ls in order_lst:
        if o_ls > 0 :
            if 0 not in use_lst : # 주차공간이 없는 경우 wait_lst에 등록
                wait_lst.append(o_ls)

            for i in range(len(use_lst)):
                if use_lst[i] == 0 : # 주차공간 비워져있음
                    use_lst[i] = o_ls # q에 해당하는 차량 주차
                    break

        else: # 차량이 주차장 밖으로 나가는 코드
            idx = use_lst.index(abs(o_ls))
            use_lst[idx] = 0 # 나갈 경우 0 (비움)
            sum += R_i[idx] * W_i[abs(o_ls)-1]

        if wait_lst:
            for i in range(len(use_lst)):
                if use_lst[i] == 0:
                    use_lst[i] = wait_lst.popleft()
    print(f"#{test_case} {sum}")

 

1. 받아야 할 입력 값들을 각각 받는다. 

 

2. 더 추가 되어야 할 리스트는 "주차 사용 여부" , "대기 차량 리스트" 이다.

 

3. 차량이 들어오고 나가는 순서로 for 문을 만들어 준다. 

 

4. 

(1) : 차량이 들어 올 때 (0 보다 큰 값)

-> 먼저 주차 공간이 있는지 확인 해준다. 주차 공간이 없다면 wait_lst에 등록  (특수 상황)

-> 주차 공간이 비워져 있을 때, 주차공간 앞에서 부터 주차 , 주차 완료하면 반복문 break로 종료 

 

(2) : 차량이 밖으로 나갈 때 (0 보다 작은 값)

-> 먼저 "주차 사용 여부"에서 주차되고 있는 차량의 인덱스를 알아낸다.

-> 그리고 0 (나감)으로 표시하고,  주차비를 계산한다.

 

(3) : 주기적으로 주차장이 비워져 있나 확인하고, 비워져 있다면 바로 대기 차량 입장

 

이 문제에서 크게 신경써야 할 포인트는 3가지이다. 

1. "차량 출입 "

2. "차량 출차 "

3. "대기 차량 출입"

이렇게 포인트를 잡아서 각각의 기능들을 추가하면 된다.

내가 이 문제를 풀었을 때, 엄청 오래걸렸는데 포인트를 잡지못하고 앞만 보고 가서 문제가 됐다. 

 

 

 

📌 "문제가 됐던 코드" 리뷰

T = int(input())
for test_case in range(1, T + 1):
    n, m = list(map(int, input().split()))
    R_i = [int(input()) for _ in range(n)]
    W_i = [int(input()) for _ in range(m)]
    order_lst = deque(int(input()) for _ in range(m*2))
    use_lst = [0] * n # 주차 사용가능 여부
    wait_lst = deque()  # 대기 차량 리스트
    sum = 0

    while order_lst:
        q = order_lst.popleft()
        if q > 0 :

            if 0 not in use_lst : # 주차공간이 없는 경우 wait_lst에 등록
                wait_lst.append(q)

            for i in range(len(use_lst)):
                if use_lst[i] == 0 : # 주차공간 비워져있음
                    use_lst[i] = q # q에 해당하는 차량 주차
                    break

        else: # 차량이 주차장 밖으로 나가는 코드
            idx = use_lst.index(abs(q))
            use_lst[idx] = 0 # 나갈 경우 0 (비움)
            sum += R_i[idx] * W_i[abs(q)-1]

        if wait_lst:
            for i in range(len(use_lst)):
                if use_lst[i] == 0:
                    use_lst[i] = wait_lst.popleft()
    print(f"#{test_case} {sum}")

 

위에 쓴 코드와 거의 비슷하지만, 지금 해당 코드는 공간초과의 문제를 가졌다.

주요 문제로는 order_lst를 Queue로 작성했기 때문이다. 

나는 queue를 써서 문제푸는 것을 좋아했는데, 이번에 이렇게 문제가 된 것이다. 

Queue로 문제를 풀고자 할 때는, 꼭 써야 할 때 쓰자 

 


📚 문제

부지런한 진용이는 정문 앞에서 유료 주차장 운영하고 있다. 이 주차장은 1 부터 n 까지 번호가 매겨진 n 개의 주차 공간을 가지고 있다.
매일 아침 모든 주차 공간이 비어 있는 상태에서 영업을 시작하며, 다음과 같은 방식으로 운영된다.

차가 주차장에 도착하면, 진용이는 비어있는 주차 공간이 있는지 검사한다.
 
비어있는 공간이 없다면, 빈 공간이 생길 때까지 차량을 입구에서 기다리게 한다.
 
빈 주차 공간이 있으면 진용이는 곧바로 주차를 시키며, 주차 가능한 공간 중 번호가 가장 작은 주차 공간에 주차하도록 한다.
 
만약 주차를 기다리는 차량이 여러 대라면, 입구의 대기장소에서 자기 차례를 기다려야 한다. 운전자들은 예의가 바르기 때문에 새치기를 하지 않는다.
 
주차요금은 차량의 무게와 주차 공간마다 따로 책정된 단위 무게당 금액을 곱한 가격이다. 진용이네 주차장에서는 종일 이용권만을 판매하기 때문에 이용시간은 고려하지 않는다.

진용이는 오늘 주차장을 이용할 m 대의 차량들이 들어오고 나가는 순서를 알고 있다.
진용이의 주차장이 오늘 하루 벌어들일 총 수입을 계산하는 프로그램을 작성하라.

[입력]


첫 번째 줄에 테스트 케이스의 수 TC 가 주어진다.
이후 TC 개의 테스트 케이스가 새 줄로 구분되어 주어진다.
각 테스트 케이스는 다음과 같이 구성되어 있다.

첫 번째 줄에 자연수  n 과  m 이 주어진다. (1 ≤ n  ≤ 100, 1 ≤ m  ≤ 2000)
n 개의 줄에 i 번째 주차 공간의 단위 무게당 요금 Ri 가 정수로 주어진다. (1 ≤ Ri  ≤ 100)
m 개의 줄에 차량 i 의 무게 Wi 가 정수로 주어진다. 차량번호 i 와 차량의 도착 순서는 아무런 관계가 없다. (1 ≤ Wi  ≤ 10000)
이후  2m 개의 줄에 차량들의 주차장 출입 순서가 하나의 정수  x 로 주어진다.
주어진 정수 x 가 양수면, x 번 차가 주차장에 들어옴을 뜻한다.
x 가 음수면, -x 번 차가 주차장을 나감을 뜻한다.

주차장에 들어오지 않은 차량이 주차장에서 나가는 경우는 주어지지 않는다.
1 번부터 m 번까지 모든 차량은 정확하게 한 번씩 주차장에 들어오고, 한 번씩 주차장에서 나간다.
또한 입구에서 대기 중인 차량이 주차를 하지 못하고 그냥 돌아가는 경우는 없다.

[출력]

각 테스트 케이스마다 ‘#t ’(t 는 테스트케이스 번호를 의미하며 1부터 시작한다)를 출력하고, 진용이가 오늘 하룻동안 벌어들일 수입을 출력하라.