题目描述
十三号星期五真的很不常见吗?每个月的十三号是星期五的频率是否比一周中的其他几天低?
请编写一个程序,计算 $N$ 年内每个月的 $13$ 号是星期日,星期一,星期二,星期三,星期四,星期五和星期六的频率。
测试的时间段将会开始于$ 1900 年 1 月 1 日 $,结束于 $ 1900 + N − 1 年 12 月 31日 $。
一些有助于你解题的额外信息:
$1、$1900 年 1 月 1 日是星期一。
$2、$在一年中,4 月、6 月、9 月、11 月每个月 30 天,2 月平年 28 天,闰年 29 天,其他月份每个月31天。
$3、$公历年份是 4 的倍数且不是 100 的倍数的年份或者公历年份是400的倍数的年份为闰年。
输入格式
共一行,包含一个整数 N。
输出格式
共一行,包含七个整数,整数之间用一个空格隔开,
依次表示星期日,星期一,星期二,星期三,星期四,星期五,星期六在十三号出现的次数。
输入样例
20
输出样例
36 33 34 33 35 35 34
(暴力枚举) O(400 * 366 ≈ 15W)
- 从
1900
年1
月1
日开始枚举, 一直枚举到1900 + N - 1
年12
月31
日 - 第一天是是星期
一
, 每天递增1
- 特判
13
号就记录一次到数组cnt[7]
C++ 代码
#include <iostream>
using namespace std;
int cnt[7];
// 判断是否闰年
bool isRunNian(int y){
return (y % 4 == 0 && y % 100 != 0) or (y % 400 == 0);
}
// 传入年月 -> 天数
int getDay(int y, int m){
switch(m){
case 1:case 3:case 5:case 7:case 8:case 10:case 12 : return 31;
case 4:case 6:case 9:case 11 : return 30;
case 2 : return isRunNian(y) ? 29 : 28;
}
}
int main(){
int n;
cin >> n;
int weekday = 0;
for (int y = 1900; y <= 1900 + n - 1; y ++ )
for (int m = 1; m <= 12; m ++ )
for (int d = 1; d <= getDay(y, m); d ++ )
{
weekday ++;
if(d == 13) cnt[weekday % 7] ++;
}
// 题意好像和样例给的不太一样, 顺序是从星期六开始..
for (int i = 6; i < 6 + 7; i ++) cout << cnt[i % 7] << ' ';
return 0;
}
从星期六开始,看了半天题解都没懂,lz给讲明白了
加油hh