문제 설명
모듈러 연산을 하는 문제입니다.
N의 범위가 명시되지 않아 TLE를 예측할 수 없지만, 혹시 모를 효율성을 위해 모듈러 연산을 해주었습니다.
자세한 설명은 소스코드에 주석을 달아두었습니다.
소스 코드
Python
N = int(input())
# answer : 월,화,수,목,금,토,일의 횟수 저장
answer = [0]*7
# 12개월 초기 세팅
# month[0]은 0 처리
# 구현의 편의성을 위하여 1월~12월의 인덱스를 갖는다. (0~12)
# 예시) 1월은 index 0이 아니라 1을 가리킨다. 12월은 index 12를 가리킨다.
month = [31]*13
month[0]=0
month[4]=30 # 4,6,9,11월은 30일
month[6]=30
month[9]=30
month[11]=30
# day : 요일을 가리킨다 (월,화,수,목,금,토,일)
# 월요일은 0이다.
# 모듈러 연산을 통해 요일을 골라낼 수 있다.
day = 0
for year in range(1900,1900+N):
month[2] = 28 #평년은 2월이 28일
if (year%4==0 and year%100!=0) or year%400==0: #윤년의 조건(문제에 명시되어 있음)
month[2] = 29 #윤년은 2월이 29일
for mth in range(1,13):
# -1을 하는 이유는
# 1900년 1월 1일에서 13번째 요일을 계산해보면 쉽게 알 수 있다.
# -1을 하지 않으면 6으로 일요일을 가리키게 되므로 13번째 요일인 토요일을 가리키려면 -1을 해줘야 한다.
answer[(day+13)%7-1]+=1
day = (day+month[mth])%7 #1개월 후의 시작 요일로 갱신해 준다.
for i in answer: #횟수 계산이 끝났다면 최종적으로 포맷에 맞게 출력한다.
print(i,end=' ')
Java8
import java.util.Arrays;
import java.util.Scanner;
public class Main_jungol_2078_13일의금요일 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int[] month = new int[13]; //1월~12월까지 일 수를 표기할 배열 생성
// 1월은 31일, 2월은 28일 또는 29일 ,,,
Arrays.fill(month, 31);
month[4]=30;//4,6,9,11월은 30일(문제에 명시)
month[6]=30;
month[9]=30;
month[11]=30;
int answer[] = new int[7];//각 요일의 횟수를 저장(index는 day변수와 동일)
int day = 0;//요일을 저장 (월요일:0, 일요일:6)
//1900년 ~ 1900+N-1년까지 계산
for(int year=1900;year<1900+N;year++) {
month[2] = 28;//평년은 2월이 28일
if((year%4==0 && year%100!=0)||year%400==0)//윤년인 경우
month[2] = 29;//윤년은 2월이 29일
for(int mth=1;mth<=12;mth++) {//12개월 순환
// -1을 하는 이유는
// 1900년 1월 1일에서 13번째 요일을 계산해보면 쉽게 알 수 있다.
// -1을 하지 않으면 6으로 일요일을 가리키게 되므로 13번째 요일인 토요일을 가리키려면 -1을 해줘야 한다.
// java의 경우 python과 달리 음수가 되는 경우도 생각해야 한다. 예) (day+13)%7이 0이 되는 경우
answer[(day+13)%7==0?6:(day+13)%7-1]++;
day = (day+month[mth])%7;//1개월 후의 `시작 요일`로 갱신해 준다.
}
}
for(int count:answer) {
System.out.print(count+" ");
}
}
}