Stay Hungry Stay Foolish

SWEA

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

dev스카이 2024. 11. 14. 22:26

[문제 링크] 👇

 

SW Expert Academy

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

swexpertacademy.com


풀이 방법

주차장과 대기열 설정

  • 주차장 리스트, 대기열 리스트, 주차 요금을 저장할 리스트를 생성한다.

차량 입출차 처리

  • 차량이 입차할 때(car > 0)
    • 주차장에 여유가 있는 경우(0 in parking) 비어있는 첫 번째 주차 공간에 차량을 저장하고 요금을 계산한다.
    • 주차장이 가득 찬 경우(0 not in parking) 해당 차량을 대기열 리스트에 추가한다.
  • 차량이 출차할 때(car < 0)
    • 주차장 리스트에서 나가는 차량의 인덱스를 찾아 해당 공간을 비운다. (index() 사용)
      • 해당 공간을 0으로 만든다.
    • 대기 중인 차량이 있는 경우, 대기 차량 중 가장 먼저 대기한 차량 즉, 대기열 리스트에 첫 번째 인덱스를 꺼낸다.
    • 출차한 차량이 있던 주차 공간에 차량을 저장하고, 요금을 계산한다.

결과 출력

  • 각 테스트 케이스마다 누적된 요금을 출력한다.

Solution

T = int(input())  # 테스트 케이스 수
for test_case in range(1, T + 1):
    N, M = map(int, input().split())  # 주차 공간, 차량 수
    R = [int(input()) for _ in range(N)]  # 단위 무게당 금액
    W = [int(input()) for _ in range(M)]  # 차량 무게

    parking = [0]*N  # 주차장
    waiting = []  # 기다리고 있는 차량
    result = 0  # 주차 요금

    for _ in range(M * 2):
        car = int(input())  # 차량 출입 순서

        if car > 0:  # 들어오는 차량일 때
            if 0 not in parking:  # 주차 공간이 없으면 대기시키기
                waiting.append(car)
            else:
                for i in range(N):  # 주차 공간 탐색
                    if parking[i] == 0:  # 주차 공간이 비어있으면
                        parking[i] = car  # 주차 시키기
                        result += R[i] * W[car - 1]  # 요금 계산
                        break

        else:  # 나가는 차량일 때
            now_idx = parking.index(abs(car))  # 나가는 차량 인덱스
            parking[now_idx] += car  # 해당 차량이 들어있는 인덱스 찾아서 0으로 만들기
            if len(waiting) != 0:  # 대기하고 있는 차량이 있을 때 주차시키기
                waiting_car = waiting.pop(0)
                parking[now_idx] = waiting_car  # 주차시키기
                result += R[now_idx] * W[waiting_car - 1]  # 요금 계산

    print(f"#{test_case} {result}")

 

 

개선할 점

  • 출차 처리 개선
    • car가 출차일 때, parking[now_idx] += car로 다시 더해 0을 만드는 대신, parking[now_idx] = 0으로 명확히 비워주는 것이 가독성이 좋다.
  • 출입 순서 입력 관리
    • car의 출입 순서 입력을 미리 리스트로 만들어 두고 순서대로 처리하면 입출력을 줄여 코드의 효율성을 높일 수 있다.
  • 불필요한 반복 줄이기
    • 0 not in parking으로 공간이 없음을 확인하고 waiting에 추가하는 것보다, parking 리스트의 빈 공간을 next_free_space와 같은 변수로 관리하면 반복문을 줄일 수 있다.

개선된 코드

T = int(input())  # 테스트 케이스 수
for test_case in range(1, T + 1):
    # 동일
    for _ in range(M * 2):
        car = int(input())  # 차량 출입 순서

        if car > 0:  # 들어오는 차량일 때
            parked = False
            for i in range(N):  # 주차 공간 탐색
                if parking[i] == 0:  # 주차 공간이 비어있으면
                    parking[i] = car  # 주차 시키기
                    result += R[i] * W[car - 1]  # 요금 계산
                    parked = True
                    break
            if not parked:  # 주차 공간이 없으면 대기시키기
                waiting.append(car)

        else:  # 나가는 차량일 때
            car = abs(car)
            now_idx = parking.index(car)  # 나가는 차량 인덱스
            parking[now_idx] = 0  # 해당 공간 비우기
            if waiting:  # 대기 차량이 있으면 주차시키기
                waiting_car = waiting.pop(0)
                parking[now_idx] = waiting_car
                result += R[now_idx] * W[waiting_car - 1]  # 요금 계산

    print(f"#{test_case} {result}")

👩‍💻 회고

이 문제를 풀 때 답이 올바르게 나오지 않았던 적이 있었다. 다음은 에러가 났을 때의 코드이다.

 

1. 차량 출차 시킬 때

parking[now_idx] -= car
  • 출차하는 차량은 음수인데 -(마이너스) 를 해버리면 +(플러스) 가 되어서 0이 되지 않고 값이 더해진다.
  • 단순하게 생각해서 마이너스 할 거니깐 그대로 - 를 했더니 값이 증가 됐다.

2. 요금 계산 시 인덱스 

result += R[i] * W[car]
result += R[now_idx] * W[waiting_car]
  • 리스트 인덱스가 0부터 시작하는데 차량을 그대로 인덱스에 집어넣어서 IndexError 가 떴다.

3. 주차 공간이 없을 때

if 0 not in parking:  # 주차 공간이 없으면 대기시키기
    waiting.append(car)
  • 이 코드에는 문제가 없지만 순서가 잘못 됐었다.
  • 주차 공간을 탐색하는 루프문 아래에 이 코드를 넣었더니 차량을 주차시키고 난 후에 이 조건을 확인하게 돼서 주차를 시켰음에도 해당 차량이 대기열로 들어가게 되는 문제가 발생했었다.

 

이런 문제들 때문에 차량이 출입하고 출차하는 과정을 일일이 출력해보면서 확인했다. 덕분에 문제를 바로 발견하고 잘 해결했다. 지문 설명이 아주 잘 돼 있고 단순 구현이라 설명하는대로만 코드를 작성하면 어렵지 않게 풀 수 있을만한 문제였다.