Skip to content

1341-十三号星期五基姆拉尔森计算公式

1341. 十三号星期五(基姆拉尔森计算公式)

原题链接

描述

13号星期五真的很不常见吗?

每个月的13号是星期五的频率是否比一周中的其他几天低?

请编写一个程序,计算 N 年内每个月的 13 号是星期日,星期一,星期二,星期三,星期四,星期五和星期六的频率。

测试的时间段将会开始于 1900 年 1 月 1 日,结束于 1900+N-1 年 12 月 31 日。

一些有助于你解题的额外信息:

1900 年 1 月 1 日是星期一。在一年中,4 月、6 月、9 月、11 月每个月 30 天,2 月平年 28 天,闰年 29 天,其他月份每个月 31 天。公历年份是 4 的倍数且不是 100 的倍数的年份为闰年,例如 1992 年是闰年,1990 年不是闰年。公历年份是整百数并且是 400 的倍数的年份也是闰年,例如 1700 年、1800 年、1900 年、2100 年不是闰年,2000 年是闰年。

输入格式
共一行,包含一个整数 N。

输出格式
共一行,包含七个整数,整数之间用一个空格隔开,依次表示星期六,星期日,星期一,星期二,星期三,星期四,星期五在13号出现的次数。

数据范围
1≤N≤400

输入样例:

20

输出样例:

36 33 34 33 35 35 34

分析

基姆拉尔森计算公式w = (d + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400 + 1) % 7
在公式中 d 表示日期中的日数,m 表示月份数,y 表示年数。
w 表示星期,w 的取值范围是 0~6,0 代表星期日,1~6 代表星期一到星期六。
注意:在公式中,把 1 月和 2 月看成是上一年的 13 月和 14 月。
例:2004-1-10 参与计算时需要换算成:2003-13-10

代码

cpp
#include <bits/stdc++.h>
using namespace std;

int week(int y, int m, int d) {
    if (m == 1 || m == 2) m += 12, y--;  // 特判1月和2月改为13月和14月,且年份改为上一年
    return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400 + 1) % 7;  // 基姆拉尔森计算公式
}

int ans[10];  // 存储答案

int main() { int n; cin >> n; for (int i = 1900; i < 1900 + n; i++) { // i枚举年份 for (int j = 1; j <= 12; j++) { // j枚举月份 ans[week(i, j, 13)]++; } } // 输出答案 cout << ans[6] << " " << ans[0] << " "; for (int i = 1; i < 6; i++) { cout << ans[i] << " "; }

return 0;

}