tag: 枚举

思路1

根据年份,构造回文日期,用check函数判断。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>

using namespace std;

unordered_map<int, int> mp = {{1, 31}, {3, 31}, {4, 30}, {5, 31}, {6, 30}, 
                              {7, 31}, {8, 31}, {9, 30}, {10, 31}, {11, 30},
                              {12, 31}};

string a, b;
int ay, am, ad, by, bm, bd;

// 按符合题意的条件以及日期构造常识判断
bool check(int y, int m, int d) {
    if (m > 12 || m == 0) return false;
    if (d == 0 || d > 31) return false;
    if (y == ay) {
        if (am > m) return false;
        else if (am == m && d < ad) return false;  
    }
    if (y == by) {
        if (m > bm) return false;
        else if (bm == m && d > bd) return false;
    }
    if (m == 2) {
        return (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) ? d <= 29 : d <= 28;
    } else {
        return d <= mp[m];
    }
    return true;
}

int main() {
    cin >> a >> b;
    ay = stoi(a.substr(0, 4)), am = stoi(a.substr(4, 2)), ad = stoi(a.substr(6, 2));
    by = stoi(b.substr(0, 4)), bm = stoi(b.substr(4, 2)), bd = stoi(b.substr(6, 2));
    int ans = 0;
    for (int y = ay; y <= by; y ++ ) {
        string t = to_string(y);
        reverse(t.begin(), t.end());
        int m = stoi(t.substr(0, 2)), d = stoi(t.substr(2));
        if (check(y, m, d)) ans ++ ;
    }
    cout << ans << endl;
    return 0;
}

思路2

可以看出,通过年份来构造日期,还要判断日期超出范围和年份为闰年等,十分复杂。而通过月日构造回文日期,可以避免复杂的合法日期的判断,操作数大概为12*31,满足题目时间要求。

注意到,当m=2时,02回文构造为20,显然是4的整数倍,不是100的整数倍,所以构造的一定是闰年,m[2]可以直接写29。

#include <iostream>
using namespace std;
 
int m[13]= {0,31,29,31,30,31,30,31,31,30,31,30,31};

int main() {
    int a, b;
    cin >> a >> b;
    int cnt = 0;
    for (int i = 1; i <= 12; i ++ )
        for (int j = 1; j <= m[i]; j ++ ) {
            int x = (j % 10) * 1e7 + (j / 10) * 1e6 + (i % 10) * 1e5 + (i / 10) * 1e4 + 
                i * 100 + j;
            if (x >= a && x <= b) cnt ++ ;
        }
    cout << cnt << endl;
}