재운이는 이 구역의 소문난 오컬트 매니아다. 늘 도서관에서 오컬트 서적을 읽고 외계문물 스터디에 참여하던 재운이는 어느 날 엄청난 소문을 듣게 되었다. 소문의 정체는 지구의 미래에 관한 예언이었는데, 그 예언에 따르면 2019년부터 다가오는 13일의 금요일의 수를 세지 않으면 지구가 멸망할 수 있다고 한다. 평소 배려심이 넘치는 재운이는 자신 뿐만 아니라 자신의 후세들을 위해 앞으로 기원 후 100,000년 까지 누적되는 13일의 금요일의 수를 매 년도마다 기록하기로 했다. 하지만 계산에 약한 재운이는 온갖 계산을 우리에게 떠맡겼다. 재운이를 도와 2019년부터 N년까지 누적되는 13일의 금요일의 수를 계산하여 알려주자.
첫째 줄에 정수 N이 입력된다. (2019 ≤ N ≤ 100,000)
첫째 줄에 2019년부터 N년까지 누적되는 13일의 금요일의 수를 출력한다
✨ Methodology
매년 돌면서, 각 월마다 13일이 금요일인지 확인하기
이 문제를 풀기 위해서 2019년 1월 1일의 요일을 확인해보았다. 1월 1일은 화요일로, 요일 배열을 만들 때 중요하게 작용한다 (직접 찾아봤는데 힌트에 써있었다...)
이 문제를 풀기 위해서는 윤년에 대해서 이해할 필요가 있다.
2월은 28일 혹은 29일까지 있는데, N이 년도일 때,
위 조건을 코드로 표현하면, 아래와 같다.
if((N % 4==0 && N % 100!=0)||N % 400==0 )
각 월별 일수를 저장한 배열과 요일 배열이 필요하다.
일수 배열은
static int[] days = {0,31,28,31,30,31,30,31,31,30,31,30,31};
로 표현하였다.
for(int i = 2019; i<=N ; i++) {//년
if((i%4==0 && i%100!=0)||i%400==0 ){//윤년일 경우 ->2월에 +1
days[2] = 29;}
else {days[2]=28;}//윤년이 아닐 경우
//inner for loop
}
for(int i = 2019; i<=N ; i++) {//년
if((i%4==0 && i%100!=0)||i%400==0 ){//윤년일 경우 ->2월에 +1
days[2] = 29;}
else {days[2]=28;}//윤년이 아닐 경우
for(int j = 1; j<=12;j++) {//월
if(date[(total_days+13)%7]==5) {//13해당 월의 13일이 금요일인가?
//System.out.println(i+"년"+j+"월"); //몇년 몇월달의 13일이 금요일인지 확인 가능
freaky_fridays++;} //13일이 금요일이면 카운트 ++
total_days+=days[j];}//확인이 끝났다면 해당 월의 일수를 총 일수에 더한다
}
총 일수에 13을 더하고 금요일인지 확인한 후, 해당 월에 남은 일수를 더할 수도 있지만 개인적으로 직접 더하지 않고 전월까지의 총 일수+13일 % 7 로 이번달의 13일이 금요일인지 확인한 후, 해당 월의 총 일수를 더하는 방식이 더 쉽게 느껴져서 위처럼 코딩하였다.
✨ 전체 소스 코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class BOJ_16463_13일의금요일 {
static int[] days = {0,31,28,31,30,31,30,31,31,30,31,30,31};
static int[] date = {1,2,3,4,5,6,7};//월~일 : 1월 1일이 화요일임
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());//2019~N년
int freaky_fridays = 0;//13일의 금요일
int total_days = 0;
for(int i = 2019; i<=N ; i++) {//년
if((i%4==0 && i%100!=0)||i%400==0 ){//윤년일 경우 ->2월에 +1
days[2] = 29;
}
else {days[2]=28;}//윤년이 아닐 경우
//Base Case:
for(int j = 1; j<=12;j++) {//월
if(date[(total_days+13)%7]==5) {
//System.out.println(i+"년"+j+"월");
freaky_fridays++;}
total_days+=days[j];}
}
System.out.println(freaky_fridays);
}
}