题解:P14042 [SDCPC 2019] Calandar

· · 题解

题意

给定两个年月日日期以及第一个日期的星期数,求第二个年月日是星期几。(30 天一个月,一周五天)

思路

求第二个日期的星期数,需要先求出两个日期之间相差的天数,然后用天数对 5 取模求出星期数。

如果考虑暴力,从第一个日期开始往后算,由于年份最大为 10^9,所以超时的风险很大。

事实上,想要计算相差的天数可以简化计算过程:

Code

#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
using namespace std;
typedef long long ll;
ll t, y1, m1, d1, y2, m2, d2, del, wkn;
string wk;
bool checkswp(){ // 检查日期是否需要交换
    if(y1 > y2) return true;
    if(y1 == y2 && m1 > m2) return true;
    if(y1 == y2 && m1 == m2 && d1 > d2) return true;
    return false;
}
void swp(){ // 交换日期
    swap(y1, y2);
    swap(m1, m2);
    swap(d1, d2);
    return ;
}
ll gabs(ll x){ // 获取取模结果
    return ((x >= 0LL) ? x : (x + 5)); // 负数取模需要加上除数
}
int main()
{
    scanf("%lld", &t);
    while(t--){
        scanf("%lld%lld%lld", &y1, &m1, &d1);
        cin >> wk;
        // 获取日期
        if(wk == "Monday") wkn = 0LL;
        else if(wk == "Tuesday") wkn = 1LL;
        else if(wk == "Wednesday") wkn = 2LL;
        else if(wk == "Thursday") wkn = 3LL;
        else if(wk == "Friday") wkn = 4LL;
        scanf("%lld%lld%lld", &y2, &m2, &d2);
        // 交换日期
        bool ifswp = checkswp();
        if(ifswp) swp();
        // 求差值
        if(m1 == m2) del = d2 - d1;
        else{
            ll tmp;
            if(y1 == y2) tmp = (m2 - m1 - 1LL) * 30LL;
            else tmp = (10 - m1 + m2) * 30LL + (y2 - y1 - 1LL) * 360LL;
            del = d2 + 30LL - d1 + tmp;
        }
        if(ifswp) del = -del;
        wkn = gabs((wkn + del) % 5LL); // 计算日期
        // 输出
        switch(wkn){
            case 0LL:
                puts("Monday");
                break;
            case 1LL:
                puts("Tuesday");
                break;
            case 2LL:
                puts("Wednesday");
                break;
            case 3LL:
                puts("Thursday");
                break;
            case 4LL:
                puts("Friday");
                break;
        }
    }
    return 0; // 结束 (。・ω・。)
}

/*
你好啊,我是 vzAczA。
趁 UNNN 不在,我把这个代码修改了一下。
因此你是不能通过复制粘贴这个代码来通过本题的。
祝你好运^ ^
*/