复赛二:回文日期

洛谷:P2010
OJ: 4951

代码说明:

  1. isLeapYear 函数:判断年份是否为闰年。
  2. getDaysInMonth 函数:根据年份和月份获取该月的天数。
  3. isPalindromeDate 函数:将日期格式化为8位字符串并判断是否为回文。
  4. incrementDate 函数:实现逐日递增的逻辑。
  5. parseDate 函数:将输入的8位数字拆分为年、月、日。
  6. 主逻辑:从起始日期遍历到终止日期,逐日递增并检查是否为回文。

代码实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <string>
using namespace std;

// 判断某一年是否是闰年
bool isLeapYear(int year) {
    // 闰年条件:年份是400的倍数,或者是4的倍数但不是100的倍数
    return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0);
}

// 根据年份和月份,返回该月的天数
int getDaysInMonth(int year, int month) {
    // 二月需要根据是否闰年决定是28天还是29天
    if (month == 2) {
        return isLeapYear(year) ? 29 : 28;
    }
    // 四月、六月、九月、十一月是30天
    if (month == 4 || month == 6 || month == 9 || month == 11) {
        return 30;
    }
    // 其他月份是31天
    return 31;
}

// 判断一个日期是否为回文日期
bool isPalindromeDate(int year, int month, int day) {
    // 将年、月、日合并为一个8位数字字符串
    string date = to_string(year * 10000 + month * 100 + day);
    // 如果日期不足8位,则需要补齐前导0(比如月份或日期为1位数时)
    while (date.length() < 8) {
        date = "0" + date;  // 在最前面添加一个'0'
    }
    // 检查字符串是否为回文,即从左往右第i位等于从右往左第i位
    for (int i = 0; i < 4; ++i) {
        if (date[i] != date[7 - i]) {  // 对比相应的左右字符
            return false;  // 如果有不相等的字符,则不是回文
        }
    }
    return true;  // 所有字符匹配,返回true
}

// 将日期增加一天
void incrementDate(int &year, int &month, int &day) {
    day++;  // 日期增加一天
    // 如果当前日期超过了该月的天数,则月份加1,日期重置为1
    if (day > getDaysInMonth(year, month)) {
        day = 1;  // 重置为1号
        month++;  // 月份增加
        // 如果月份超过12月,则年份加1,月份重置为1月
        if (month > 12) {
            month = 1;  // 重置为1月
            year++;     // 年份增加
        }
    }
}

// 将输入的8位数字解析为年、月、日
void parseDate(int date, int &year, int &month, int &day) {
    // 通过整数操作将8位日期解析为年、月、日
    year = date / 10000;  // 年份是前4位
    month = (date / 100) % 100;  // 月份是中间两位
    day = date % 100;  // 日期是最后两位
}

int main() {
    int startDate, endDate;
    cin >> startDate >> endDate;  // 输入起始日期和终止日期

    int startYear, startMonth, startDay;
    int endYear, endMonth, endDay;
    
    // 解析输入的起始和终止日期
    parseDate(startDate, startYear, startMonth, startDay);
    parseDate(endDate, endYear, endMonth, endDay);

    int count = 0;  // 计数器,统计回文日期的数量

    // 遍历从起始日期到终止日期的每一天
    while (startYear < endYear || 
           (startYear == endYear && startMonth < endMonth) || 
           (startYear == endYear && startMonth == endMonth && startDay <= endDay)) {
        // 判断当前日期是否是回文日期
        if (isPalindromeDate(startYear, startMonth, startDay)) {
            count++;  // 如果是回文日期,计数器加1
        }
        // 将日期加1
        incrementDate(startYear, startMonth, startDay);
    }

    cout << count << endl;  // 输出回文日期的总数

    return 0;
}
Scroll to Top