题解:P14042 [SDCPC 2019] Calandar

· · 题解

题目链接:P14042 [SDCPC 2019] Calandar

题目大意

给你一个日期该日期所对应的星期,让你求另一个日期所对应的星期

思路

注意事项:

  1. 每个月都只有 30 天(也就是说一年共有 360 天)。

    关于一个非常经典的问题

    题目中让我们求的问题非常经典: 给你一个日期该日期所对应的星期,让你求另一个日期所对应的星期

    暴力

    我们一天一天的进行模拟,可是数据范围太大了!我们直接超时了。所以,我们需要时间复杂度为 O(1) 的算法

    正解

    我们假设题目给出的两个日期所相差的天数k

如果 k5 的倍数,那么星期不会变化。所以,我们在暴力算法中,可以用取余来省略大量计算。

现在的思路清晰明了:

  1. 先求出两个日期所相差的天数。
  2. 在模拟求要求的日期所对应的星期。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int n,ans;
    long long m;
    long long ye1,m1,d1;
    long long ye2,m2,d2;
    string op;
    bool flag;
    map<string,int> f;
    map<int,string> k;
    void c(){//初始化函数
    f["Monday"]=0;
    f["Tuesday"]=1;
    f["Wednesday"]=2;
    f["Thursday"]=3;
    f["Friday"]=4;
    k[0]="Monday";
    k[1]="Tuesday";
    k[2]="Wednesday";
    k[3]="Thursday";
    k[4]="Friday";
    }
    long long days(long long a,long long b,long long c,long long d,long long e,long long f){//求两个日期所相差的天数的函数
    long long z=(d-a)*360+(e-b)*30+f-c;
    return z;
    }
    int main(){
    c();
    cin>>n;
    while(n--){
        cin>>ye1>>m1>>d1>>op;
        cin>>ye2>>m2>>d2;
        flag=true;
        ans=f[op];
        //以下判断是处理给出的日期比要求星期的日期时间更靠后的情况
        if(ye1>ye2){
            swap(ye1,ye2);
            swap(m1,m2);
            swap(d1,d2);
            flag=false;
        }
        else{
            if(m1>m2){
                swap(m1,m2);
                swap(d1,d2);
                flag=false;
            }
            else{
                if(d1>d2){
                    swap(d1,d2);
                    flag=false;
                }
            }
        }
        m=days(ye1,m1,d1,ye2,m2,d2)%5;
        if(flag) ans=(ans+m)%5;
        else ans=(ans+5-m)%5;
        //求出要求星期的日期所对应的星期
        cout<<k[ans]<<endl;
    }
    return 0;
    }

    总结

    这道题考察基本功,注意细节很容易就可以做出。还蛮适合考前练练手的。