코딩테스트 & 문제 풀이

[Python]백준_1340 : 연도 진행바

Hicecream 2023. 8. 16. 00:16

2022년 9월 27일에 작성됨

 

https://www.acmicpc.net/problem/1340

 

1340번: 연도 진행바

평년일 때, 각 달은 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31일이 있다. 윤년에는 2월이 29일이다. 윤년은 그 해가 400으로 나누어 떨어지는 해 이거나, 4로 나누어 떨어지면서, 100으로 나누어 떨어지지

www.acmicpc.net

 

 

문제 분석

현재 연도가 평년인지, 윤년인지 판단 한다.
윤년이면 2월의 일 수가 1일 늘어난다.

이 문제에선 시간의 최소 단위가 '분'이기 때문에 모든 날짜와 시간을 분 단위로 바꾸어 준다.

 

 

소스 코드 (⭕)

string = input().split(' ')  # 전체 문자열 공백으로 나눠 입력 받기

month = string[0]  # 문자열 string의 첫 번째 요소는 현재 월
# dd = int(string[1][0:len(string[1])-1])
dd = int(string[1][:-1])  # string의 두 번째 요소에서 맨 뒤의 콤마를 제외한 것이 현재 일

yyyy = int(string[2])  # string의 세 번째 요소는 현재 연도

hh, mm = map(int, string[3].split(':'))  # string의 네 번째 요소에서 콜론을 기준으로 분리한 것이 각각 현재 시와 분


month_name = ["January", "February", "March", "April", "May", "June",            # 모든 달의 이름
              "July", "August", "September", "October", "November", "December"]         


month_day = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]  # 각 달의 마지막 일 수 (평년 기준)


if yyyy % 400 == 0 or (yyyy % 4 == 0 and yyyy % 100 != 0):  # 만약 입력한 연도가 윤년일 때
    month_day[1] += 1  # 2월의 마지막 일 수에 +1 

all_time = sum(month_day)*24*60  # 그 해의 전체 시간을 분으로 바꾸기

month_idx = month_name.index(month)  # month_name에서 month에 해당되는 요소의 인덱스 저장

current_time = (sum(month_day[:month_idx])+dd-1)*24*60+hh*60+mm  # 현재까지의 시간을 모두 분으로 바꾸기

print(current_time/all_time*100)  # (현재 시간 / 전체 시간) * 100을 하여 이번 해가 몇 % 지났는지 출력

 

코드 분석

month dd, yyyy hh:mm과 같이 주어진다. month는 현재 월이고, yyyy는 숫자 4자리인 현재 연도이다. dd, hh, mm은 모두 2자리 숫자이고, 현재 일, 시, 분이다.

이해하기 쉽게 예제 입력 1을 입력한다고 하자.

string = input().split(' ')

"May 10, 1981 00:31"을 공백을 기준으로 나눠 string에 입력받는다.
그럼 아래와 같이 값이 들어간다.
string = ['May', '10,', '1981', '00:31']
string[0] = ['May']
string[1] = ['10,']
string[2] = ['1981']
string[3] = ['00:31']

 

month = string[0]

dd = int(string[1][:-1])

yyyy = int(string[2])

hh, mm = map(int, string[3].split(':'))

month는 그대로 string[0]이다.
dd는 string[1]인데, 마지막 콤마(,)는 빼주기 위해 슬라이스를 사용하여 [:-1]까지로 지정해준다.
yyyy도 그대로 string[2]이다.
hh와 mm은 string[3]에서 콜론(:)을 구분자로 하여 각각 시와 분으로 나눠 저장해준다.

dd, yyyy, hh, mm을 int형으로 바꿔주는 이유는, 바꿔주지 않으면 숫자여도 문자열로 취급해버리기 때문이다!

 

month_name = ["January", "February", "March", "April", "May", "June", 
              "July", "August", "September", "October", "November", "December"]

month_day = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

모든 달의 이름인 month_name과 평년 기준 각 달의 마지막 일 수인 month_day를 각각 리스트로 만들어 요소들을 넣어준다.

 

if yyyy % 400 == 0 or (yyyy % 4 == 0 and yyyy % 100 != 0):
    month_day[1] += 1

if 문을 사용하여 만약 현재 연도인 yyyy가 윤년이면, month_day에서 2월에 해당하는 month_day[1]의 요소에 +1을 해준다.

 

all_time = sum(month_day)*24*60

month_idx = month_name.index(month)                 

current_time = (sum(month_day[:month_idx])+dd-1)*24*60+hh*60+mm

print(current_time/all_time*100)

그 다음, 그 해의 전체 시간을 분으로 바꿔준다.
(sum 함수로 all_time 리스트의 합계 즉, 모든 달의 일 수를 더한 다음 * 24(시간) * 60(분)을 해준다.)

 

month_name에서 month에 해당되는 요소를 month_idx에 인덱스 값을 넣어준다.
예제 입력 1에 따르면 month는 "May"가 되고, month_name에서 5번째 요소, month_name[4] (인덱스는 4)이므로 month_idx = 4가 된다.

 

현재 시간 current_time을 모두 분 단위로 바꾼다.

 

마지막으로 (현재 시간 / 전체 시간) * 100을 하여 이번 해가 몇 % 지났는지 출력해준다.

 


 

슬라이스와 map 함수에 대한 자세한 설명은 아래 링크 참고

 

✍️ 슬라이스(slice)

https://dojang.io/mod/page/view.php?id=2208 


✍️ map 함수

https://dojang.io/mod/page/view.php?id=2286 

 

 

 

 

end

너무 어려운 문제였다...😭
코드 분석을 하다 보니까 글만 엄청 많은 것 같아서 손그림으로 설명도 넣어봤는데 괜히 넣은 것 같다,, 보기 안좋지만 고칠 기력이 없기 때문에 걍 놔두기로..