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
너무 어려운 문제였다...😭
코드 분석을 하다 보니까 글만 엄청 많은 것 같아서 손그림으로 설명도 넣어봤는데 괜히 넣은 것 같다,, 보기 안좋지만 고칠 기력이 없기 때문에 걍 놔두기로..
'코딩테스트 & 문제 풀이' 카테고리의 다른 글
[C]백준_2558 : A+B - 2 (1) | 2023.08.18 |
---|---|
[Python]백준_1343 : 폴리오미노 (0) | 2023.08.17 |
[C]백준_2742 : 기찍 N (0) | 2023.08.15 |
[C]백준_10951 : A+B - 4 (0) | 2023.07.20 |
[C]백준_10952 : A+B - 5 (0) | 2023.07.19 |