题目描述

给定一些年份的节日日期计算规则,需要计算指定年份中每个节假日的具体日期,并判断每个节假日对应的星期。

算法思路

日期模拟问题:

  1. 使用基姆拉尔森公式或直接计算某天是星期几
  2. 根据每个节日的规则(如第几个星期几是几月几日)计算具体日期
  3. 输出指定年份所有节假日的日期和星期

代码实现

#include <bits/stdc++.h>
using namespace std;
 
// 计算y年m月d日是星期几,返回0-6(0为周日)
int dayOfWeek(int y, int m, int d){
    if(m < 3){
        m += 12;
        y--;
    }
    int c = y / 100;
    int yv = y % 100;
    int w = (c / 4 - 2 * c + yv + yv / 4 + 13 * (m + 1) / 5 + d - 1) % 7;
    if(w < 0) w += 7;
    return w;
}
 
int main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);
    int a, b, c, y1, y2;
    cin >> a >> b >> c >> y1 >> y2;
    
    // a: 第几个(1-5), b: 星期几(1-7, 1为周一), c: 月份(1-12)
    for(int y = y1; y <= y2; y++){
        // 计算y年c月的第a个星期b是几号
        // 先计算c月1日是星期几
        int firstDay = dayOfWeek(y, c, 1);
        // 找到c月第a个星期b
        // 星期b对应: 1->周一, ..., 7->周日
        // 先算c月1日是星期几,然后计算目标日期
        int targetDay = 1;
        // 星期b中b=1表示周一,b=7表示周日
        // firstDay: 0=周日, 1=周一, ..., 6=周六
        int diff = b - firstDay;
        if(diff < 0) diff += 7;
        targetDay += diff + (a - 1) * 7;
        
        cout << y << " ";
        if(targetDay > 31){
            // c月没有这么多天
            cout << "none" << endl;
        }else{
            cout << targetDay << endl;
        }
    }
    return 0;
}

关键点

  • 星期计算:使用基姆拉尔森公式
  • 第n个星期几的计算:先计算该月1日是星期几,然后计算差值
  • 注意星期表示方式(周日=0还是周日=7)

参考

  • CCF-CSP认证