본문 바로가기
CS/알고리즘 & 문제풀이

[Python] 백준 9080 PC방 요금

by mintropy 2021. 10. 7.

문제 링크 : https://www.acmicpc.net/problem/9080

 

9080번: PC방 요금

현성이는 요즘 LINEAR 2라는 온라인 게임에 빠져있다. PC방에 가서 게임을 즐기는데, 자주 가는 PC방의 요금체계는 다음과 같다. 일반 요금으로 시간당 1000원 씩을 받으며, 야간 정액을 끊으면 5000원

www.acmicpc.net

1. 접근 방법

주간과 야간을 나누고, 야간에는 일반 요금과 야간 정액이 있어 적어도 3가지를 고려해야 할 것 같았다.

진행하며 보니 더욱 안정적으로 풀이하기 위해 더욱 많은 분기점이 생겼다. 하지만 큰 토대는 주간과 야간 그리고 하루가 넘어가는 것을 어떻게 잘 처리하는지인 것 같다. 그리고, 시간, 분을 각각 저장해도 되지만, 나는 00:00 기준으로 지난 시간을 분으로 계산하여 풀이했다.

 

 

2. 풀이 코드

🖥python

import sys
input = sys.stdin.readline

for _ in range(int(input())):
    st_time, duration = input().strip().split()
    # 시간 시간, 분
    st_h, st_m = map(int, st_time.split(':'))
    # 시간을 00:00 기준 지난 시간
    now = st_h * 60 + st_m
    # 총 사용 시간
    duration = int(duration)
    
    fee = 0
    while duration:
        # 만약 남은 시간이 5시간 이하면 시간별 요금 내기
        if duration <= 60 * 5:
            if duration % 60:
                fee += (duration // 60 + 1) * 1000
            else: 
                fee += (duration // 60) * 1000
            break
        # 제한시간이 더 많이 남아있을 때
        # 야간이고 남은 시간이 5시간 이상이면 정액제
        if now >= 22 * 60 or now <= 3 * 60:
            # 08:00 기준에서 지금시간까지 빼기
            if now >= 22 * 60:
                duration -= (24 + 8) * 60 - now
            else:
                duration -= 8 * 60 - now
            fee += 5000
            now = 8 * 60
        # 야간 남은 시간 5시간 미만이거나, 주간이면
        # 21:~~ 까지 사용하기
        elif 3 * 60 < now < 21 * 60:
            time = 21 - now // 60
            # 더 사용할 시간이 적으면, 모두 사용
            if time * 60 >= duration:
                if duration % 60:
                    fee += (duration // 60 + 1) * 1000
                else: 
                    fee += (duration // 60) * 1000
                break
            # time에 해당하는 시간만큼만 사용
            else:
                fee += time * 1000
                duration -= time * 60
                now += time * 60
        # 21:~~ 이라면 어떻게 할 지 고민하기
        else:
            # 21:00 이면 한시간 진행
            if now == 21 * 60:
                if duration > 60:
                    now += 60
                    fee += 1000
                    duration -= 60
                    continue
                else:
                    fee += 1000
                    break
            time = 10 * 60 + (22 * 60 - now)
            # 다음날 08:00 이후까지 하는 경우
            if duration >= time:
                now = 8 * 60
                fee += 1000 + 5000
                duration -= time
            # 야간 5시간 이상 하는 경우
            elif duration - (22 * 60 - now) >= 60 * 5:
                fee += 1000 + 5000
                break
            # 야간 5시간 미만 하는 경우
            else:
                if duration % 60:
                    fee += (duration // 60 + 1) * 1000
                else: 
                    fee += (duration // 60) * 1000
                break
    print(fee)

📕풀이 과정

조건 분기가 많지만, 기본적인 조건은 3가지로 두고 구현했다.

1. 야간 시간이면, 정액 요금과 일반요금 중 선택하여 사용

2. 주간 시간이면, 주간시간을 최대한 사용하여, 1시간 단위로 모두 사용

3. 주간 21~22시 사이라면, 야간시간을 비교하여 진행

  3-1. 해당 시간부터 야간 5시간 이상 정액 요금 사용할 때

  3-2. 해당 시간부터 야간 5시간 미만으로 일반 요금 사용할 때

 

 

3. 생각 정리

풀이과정을 마치고 나서 보니 생각보다 더욱 많은 분기가 생겼다. 다른 분기를 많이 해야하는 문제들도 비슷한 부분을 겪었는데, 이 문제에서도 분기점을 깔끔하게 정리하지 못한 것 같다.

당장 이 분기점들을 모두 정리하는것은 엄두가 나지 않지만, 조금 더 깔끔하게 문제를 정리하면 좋을 것 같다.

댓글