蓝桥杯高频考点-与日期相关的题目

前言

纵观蓝桥杯近几年的真题,与日期相关的题目经常出现

为了节省我们宝贵的比赛时间,对于与日期相关的题目,我们需要构造一套属于自己的模版

1. 如何枚举合法日期

对于日期,我们一般把它当作一个8位的数字进行处理,前四位数字是年份,第五位和第六位数字是月份,最后两位数字是当前月份的天数

一般是先枚举日期,再判断日期是否合法

1.1 预存每个月的天数

创建一个全局范围的数组,用于预存每个月的天数。

之所以要创建全局范围的数组,是为了避免函数之间的传参操作。

int days[15] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

1.2 封装一个判断日期是否合法的函数

bool isLegal(int date) {
    int year = date / 10000;
    int month = date / 100 % 100;
    int day = date % 100;
    if (month > 12 || month < 1) {
        return false;
    }
    if (day < 1 || day > 31) {
        return false;
    }
    int isLeap = 0;
    if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
        isLeap = 1;
    }
    if (month == 2) {
        if (day > days[month] + isLeap) {
            return false;
        }
    } else {
        if (day > days[month]) {
            return false;
        }
    }
    return true;
}

1.3 枚举日期并判断日期是否合法

以2024年为例,枚举2024年的所有合法日期

#include <iostream>

using namespace std;

int days[15] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool isLegal(int date) {
    int year = date / 10000;
    int month = date / 100 % 100;
    int day = date % 100;
    if (month > 12 || month < 1) {
        return false;
    }
    if (day < 1 || day > 31) {
        return false;
    }
    int isLeap = 0;
    if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
        isLeap = 1;
    }
    if (month == 2) {
        if (day > days[month] + isLeap) {
            return false;
        }
    } else {
        if (day > days[month]) {
            return false;
        }
    }
    return true;
}

int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    for (int i = 20240101; i <= 20241231; i++) {
        if (isLegal(i)) {
            cout << i << endl;
        }
    }
    return 0;
}

2. 判断日期是否为回文日期

方法2.2的运行效率远高于方法2.1

如果开始日期和结束日期相差超过100年,建议使用方法2.2

2.1 将日期当作字符串进行处理

要判断一个日期是否是回文日期,可以先将该日期转成字符串

将反转后的字符串与原字符串对比,如果相等则说明该日期是回文日期

该方法需要包含<string>头文件和<algorithm>头文件,而且C++的版本要大于等于C++11

bool check01(int date) {
    string str = to_string(date);
    string temp = str;
    reverse(temp.begin(), temp.end());
    return str == temp;
}

check01函数也可写成下面的形式(无需包含<algorithm>头文件)

bool check01(int date) {
    string str = to_string(date);
    if (str[0] == str[7] && str[1] == str[6] && str[2] == str[5] && str[3] == str[4]) {
        return true;
    }
    return false;
}

2.2 将日期当作一个8位数进行处理

将日期当作一个8位数的整数,利用基础的运算符号反转整数,然后判断反转后的整数与原整数是否相等

bool check02(int date) {
    int originalNumber = date;
    int reverseNumber = 0;

    while (date != 0) {
        reverseNumber = reverseNumber * 10 + date % 10;
        date = date / 10;
    }

    return originalNumber == reverseNumber;
}

以下例子求的是1949年到2049年之间的所有回文日期

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int days[15] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool isLegal(int date) {
    int year = date / 10000;
    int month = date / 100 % 100;
    int day = date % 100;
    if (month > 12 || month < 1) {
        return false;
    }
    if (day < 1 || day > 31) {
        return false;
    }
    int isLeap = 0;
    if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
        isLeap = 1;
    }
    if (month == 2) {
        if (day > days[month] + isLeap) {
            return false;
        }
    } else {
        if (day > days[month]) {
            return false;
        }
    }
    return true;
}

bool check01(int date) {
    string str = to_string(date);
    string temp = str;
    reverse(temp.begin(), temp.end());
    return str == temp;
}

bool check02(int date) {
    int originalNumber = date;
    int reverseNumber = 0;

    while (date != 0) {
        reverseNumber = reverseNumber * 10 + date % 10;
        date = date / 10;
    }

    return originalNumber == reverseNumber;
}

int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    for (int i = 19490101; i <= 20491231; i++) {
        if (isLegal(i) && check02(i)) {
            cout << i << endl;
        }
    }
    return 0;
}

3. 给定初始日期,计算经过n天后对应的日期

3.1 得到某年某月的天数

int getDay(int year, int month) {
    if (month != 2) {
        return days[month];
    } else {
        int leap = year % 400 || (year % 4 == 0 && year % 100 != 0);
        return 28 + leap;
    }
}

3.2 计算经过n天后的日期

int pass(int startDate, int n) {
    int year = startDate / 10000;
    int month = startDate / 100 % 100;
    int day = startDate % 100;
    for (int i = 1; i <= n; i++) {
        day++;
        if (day > getDay(year, month)) {
            month++;
            day = 1;
        }
        if (month > 12) {
            year++;
            month = 1;
        }
    }
    return year * 10000 + month * 100 + day;
}

4. 练习

4.1 回文日期

题目链接:回文日期

4.2 跑步锻炼

题目链接:跑步锻炼

4.3 日期统计

题目链接:日期统计

4.4 回文日期

题目链接:回文日期

5. 拓展-与时间相关的题目

处理时间一般会使用到运用求余、除法这两种基本运算

5.1 例题

5.1.1 题目描述


在这里插入图片描述

5.1.2 题目链接

题目链接:时间显示

5.2 解题思路

  • long long类型的数据接收数据

  • 由于题目给出的时间是以毫秒为单位的,因此要先将时间除以1000变成以秒为单位

  • 因为不需要显示年、月、日,所以要先过滤掉年、月、日的秒数

  • 最后,利用求余、除法运算得到时、分、秒

5.3 参考题解

时、分、秒不足两位时要补前导0

#include <cstdio>

using namespace std;

int main() {
    long long time;
    scanf("%lld", &time);

    time = time / 1000; // 将以毫秒为单位转化为以秒为单位
    time = time % (60 * 60 * 24); // 过滤掉年、月、日的秒数

    long long hour = time / 3600; // 一小时3600秒
    long long minute = time / 60 % 60; // 一分钟60秒
    long long second = time % 60;
    printf("%02lld:%02lld:%02lld", hour, minute, second);

    return 0;
}

相关推荐

  1. 题目-回文日期

    2024-06-07 16:38:03       42 阅读
  2. 题目 1908: -矩阵相乘

    2024-06-07 16:38:03       20 阅读
  3. 】(完全日期

    2024-06-07 16:38:03       16 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-07 16:38:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-07 16:38:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-07 16:38:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-07 16:38:03       20 阅读

热门阅读

  1. 回溯法——LQ_04 2n皇后

    2024-06-07 16:38:03       8 阅读
  2. 每天CTF小练(6.6)--基础异或

    2024-06-07 16:38:03       6 阅读
  3. 欣九康诊疗系统:营销做得好,创收没烦恼!

    2024-06-07 16:38:03       9 阅读
  4. Vue3 时间格式化

    2024-06-07 16:38:03       7 阅读
  5. mysql日志管理

    2024-06-07 16:38:03       5 阅读
  6. 系统化自学Python的实用指南

    2024-06-07 16:38:03       10 阅读
  7. python记录之元组

    2024-06-07 16:38:03       8 阅读
  8. 【Webpack4打包机制原理解析】

    2024-06-07 16:38:03       5 阅读
  9. Codeforces Round 950 (Div. 3)

    2024-06-07 16:38:03       10 阅读
  10. 【讯为Linux驱动开发】3.内核空间和用户空间

    2024-06-07 16:38:03       8 阅读