题解 SP10366 CODEIT03 - Play with Dates

题解 SP10366 CODEIT03 - Play with Dates

题目大意

给定日期(日、月、年),计算对应的星期几并输出。

算法思路

Zeller's Congruence 算法

本题要求根据日期计算星期几,可以使用 Zeller's Congruence 公式直接计算。这是一个 O(1) 时间复杂度的算法。

公式说明

h = \\left(q + \\left\\lfloor \\frac{13(m+1)}{5} \\right\\rfloor + K + \\left\\lfloor \\frac{K}{4} \\right\\rfloor + \\left\\lfloor \\frac{J}{4} \\right\\rfloor + 5J \\right) \\bmod 7

其中:

  • q = d(日)
  • 如果 m \< 3,则 m = m + 12y = y - 1
  • K = y \\bmod 100(年份后两位)
  • J = \\left\\lfloor y / 100 \\right\\rfloor(世纪数)

结果映射

计算结果 h 与星期的对应关系:

  • 0 → Saturday(星期六)
  • 1 → Sunday(星期日)
  • 2 → Monday(星期一)
  • 3 → Tuesday(星期二)
  • 4 → Wednesday(星期三)
  • 5 → Thursday(星期四)
  • 6 → Friday(星期五)

C++ 实现代码

cpp 复制代码
h = (q + (13 * (m + 1)) / 5 + k + k / 4 + j / 4 + 5 * j) % 7; // 个人习惯,改成小写

AC 代码

cpp 复制代码
#include<bits/stdc++.h>
#define youhua ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
string days[] = {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; // 星期,顺序很重要

int gs(int d, int m, int y) {
    // 预处理
    if (m < 3) { // 在 Zeller's Congruence 公式中月份范围是 3 到 14,我们要转换成现在的日期方法!
        m += 12;
        y -= 1;
    }
    int q = d;
    int m1 = m;
    int k = y % 100;
    int j = y / 100;
    // 预处理结束
    int h = (q + (13 * (m1 + 1)) / 5 + k + k / 4 + j / 4 + j * 5) % 7; // 公式
    return h; // 返回天数
}

int main() {
    youhua;
    int t;
    cin >> t;
    while (t--) {
        int d, m, y; // 这个就不用解释了吧
        cin >> d >> m >> y;
        int h = gs(d, m, y); // 套用公式
        cout << days[h] << endl;
    }
    return 0;
}

AC 记录