1. 问题背景与需求分析
黑色星期五问题是一个经典的日期计算问题,起源于西方文化中对"13号星期五"这一特殊日期的迷信。作为程序员,我们更关心的是如何用算法精确计算出特定时间段内13号落在各星期几的次数分布。
这个问题的核心在于:
- 给定一个年份范围(1900年到1900+n-1年)
- 统计这段时间内所有13号对应的星期几
- 输出从周六到周五的分布次数
注意:题目特别说明1900年1月1日是星期一,这是整个计算的时间基准点。同时给出了各月份天数的规则,包括闰年判断标准。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法设计思路
2.1 日期计算的基本方法
解决这类日期计算问题通常有三种主流方法:
- 逐日遍历法:从基准日开始一天天累加,统计所有13号的星期几
- 公式计算法:使用蔡勒公式等数学公式直接计算特定日期的星期
- API调用法:利用编程语言自带的日期库函数
对于本题而言,逐日遍历法是最直观且容易实现的方案,因为:
- 题目给出的时间范围有限(最多400年)
- 不需要处理1582年之前的格里高利历法改革问题
- 实现简单,逻辑清晰,适合编程练习
2.2 关键数据结构设计
在C++实现中,我们需要以下数据结构:
- 月份天数数组:
month[13]存储各月份天数(索引1-12对应1-12月) - 星期计数数组:
arr[8](索引1-7对应周一到周日,但题目要求输出顺序特殊)
cpp复制int month[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; // 平年各月天数
int arr[8] = {0}; // 星期计数,arr[1]=周一...arr[7]=周日
2.3 闰年判断逻辑
闰年规则是日期计算中的关键:
- 能被400整除的是闰年
- 能被4整除但不能被100整除的是闰年
- 其余都是平年
对应代码实现:
cpp复制if(i%400 == 0 || (i%4 == 0 && i%100!= 0))
month[2] = 29; // 闰年2月29天
else
month[2] = 28; // 平年2月28天
3. 代码实现详解
3.1 主循环结构
程序采用三层循环结构
