F 日期小助手(“科大讯飞杯” 暴力)

F 日期小助手

“科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛

题目描述
作为一个关心父母的孩子,Compute 会在每年的母亲节和父亲节为父母准备礼物。可是粗心的他却不记得它们的具体日期了。
已知:母亲节在每年 5 月的第 2 个周日;父亲节在每年 6 月的第 3 个周日。
现在你需要告诉他,下一个(不包括当天)母亲节或父亲节是在什么时候。
输入描述:
第一行包含一个整数 T ( T ≤ 100 ) T (T \leq 100) T(T100),表示测试数据的组数。
对于每组数据,包含三个整数 y, m, d,中间以空格分隔,分别表示今天的年、月、日。
输入保证是一个在公元 2000 年 1 月 1 日 到 2100 年 12 月 31 日间的合法日期。
输出描述:
对于每组数据,在一行输出下一个需要准备礼物的节日和日期。格式参考样例输出。

输入

7
2000 1 1
2001 1 1
2002 1 1
2003 1 1
2020 1 1
2020 5 10
2020 6 21

输出

Mother's Day: May 14th, 2000
Mother's Day: May 13th, 2001
Mother's Day: May 12th, 2002
Mother's Day: May 11th, 2003
Mother's Day: May 10th, 2020
Father's Day: June 21st, 2020
Mother's Day: May 9th, 2021

备注:
注意在冒号和逗号后面有一个空格。

思路:
从2000年到2100年底,还要加上2102年一年,一共 365 × 102 = 37230 365 \times 102 = 37230 365×102=37230 天左右, T = 100 T=100 T=100 ,总的时间复杂度也才 O ( 3723000 ) O(3723000) O(3723000),所以我们可以对每个日期暴力一遍。

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 40005;

int months[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

string s[10] = {"", "st", "nd", "rd"};
string deal(int x)
{
    int m = x % 10;
    if (x == 11 || x == 12 || x == 13)
        return "th";
    if (m == 1 || m == 2 || m == 3)
        return s[m];
    return "th";
}

struct node
{
    int Y, M, D, W;
} a[N];

bool judge_run(int Year)
{
    if (Year % 400 == 0 || (Year % 4 == 0 && Year % 100 != 0))
        return true;
    else
        return false;
}

int main()
{
#ifdef LOCAL_LIUZHIHAN
    freopen("in.in", "r", stdin);
    // freopen("out.out", "w", stdout);
#endif
    int i, yy = 2000, mm = 1, dd = 1, ww = 6;
    for (i = 1; i < N; i++) //从 2000.1.1 开始往后预处理 40000 天,记下每天的 年 月 日 星期
    {
        a[i].Y = yy;
        a[i].M = mm;
        a[i].D = dd;
        a[i].W = ww;
        ww = ww % 7 + 1;
        dd++;
        if (dd == months[mm] + 1)
        {
            dd = 1;
            mm++;
            if (mm == 13)
            {
                mm = 1;
                yy++;
                if (judge_run(yy))
                {
                    months[2] = 29;
                }
                else
                {
                    months[2] = 28;
                }
            }
        }
    }
    int T, y, m, d;
    cin >> T;
    while (T--)
    {
        cin >> y >> m >> d;
        int r5 = 0, r6 = 0;
        bool f = false;
        int c5 = 0, c6 = 0;
        for (i = 1; i < N; i++)
        {
            if (a[i].M == 5 && a[i].W == 7)
            {
                c5++;
                if (c5 == 2) //这是五月的第 2 个星期天
                {
                    if (f) //并且在给出的日期之后
                    {
                        r5 = i;
                        break;
                    }
                }
            }
            if (a[i].M == 6 && a[i].W == 7)
            {
                c6++;
                if (c6 == 3) //这是六月的第 3 个星期天
                {
                    if (f) //并且在给出的日期之后
                    {
                        r6 = i;
                        break;
                    }
                }
            }
            if (a[i].M == 6) //出了五月,到下一年去,要置 0
                c5 = 0;
            if (a[i].M == 7) //同上
                c6 = 0;
            if (!f && y == a[i].Y && m == a[i].M && d == a[i].D) //如果找到这一天了,f=true
            {
                // cout << "riqi:" << a[i].Y << " " << a[i].M << " " << a[i].D << " " << a[i].W << endl;
                f = true;
            }
        }
        if (r5)
        {
            cout << "Mother's Day: May " << a[r5].D << deal(a[r5].D) << ", " << a[r5].Y << endl;
        }
        if (r6)
        {
            cout << "Father's Day: June " << a[r6].D << deal(a[r6].D) << ", " << a[r6].Y << endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值