洛谷P2010《回文日期》

枚举+判断

题目描述

在日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。

牛牛习惯用88位数字表示一个日期,其中,前44位代表年份,接下来22位代表月 份,最后22位代表日期。显然:一个日期只有一种表示方法,而两个不同的日期的表 示方法不会相同。

牛牛认为,一个日期是回文的,当且仅当表示这个日期的8位数字是回文的。现 在,牛牛想知道:在他指定的两个日期之间包含这两个日期本身),有多少个真实存 在的日期是回文的。

一个88位数字是回文的,当且仅当对于所有的i ( 1 \le i \le 8)i(1≤i≤8)从左向右数的第i个 数字和第9-i9−i个数字(即从右向左数的第ii个数字)是相同的。

例如:

•对于2016年11月19日,用88位数字2016111920161119表示,它不是回文的。

•对于2010年1月2日,用88位数字2010010220100102表示,它是回文的。

•对于2010年10月2日,用88位数字2010100220101002表示,它不是回文的。

每一年中都有1212个月份:

其中,1,3,5,7,8,10,121,3,5,7,8,10,12月每个月有3131天;4,6,9,114,6,9,11月每个月有3030天;而对于22月,闰年时有2929天,平年时有2828天。

一个年份是闰年当且仅当它满足下列两种情况其中的一种:

1.这个年份是44的整数倍,但不是100100的整数倍;

2.这个年份是400400的整数倍。

例如:

•以下几个年份都是闰年:2000,2012,20162000,2012,2016。

•以下几个年份是平年:1900,2011,20141900,2011,2014。

Input / Output 格式 & 样例

输入格式

两行,每行包括一个88位数字。

第一行表示牛牛指定的起始日期。

第二行表示牛牛指定的终止日期。

保证 date_i 和都是真实存在的日期,且年份部分一定为4位数字,且首位数字不为0。

保证 date_1 —定不晚于 date_2

输出格式

一个整数,表示在 date_1 date_2 之间,有多少个日期是回文的。

输入输出样例

输入样例#1:

1
2
20110101
20111231

输出样例#1:

1
1

输入样例#2:

1
2
20000101
20101231

输出样例#2:

1
2

说明

【样例说明】

对于样例1,符合条件的日期是20111102。

对于样例2,符合条件的日期是20011002和20100102。

【子任务】

对于 60\% 的数据,满足 date1 = date2

解题思路

我们考虑直接枚举月和日。

对于每一个月,我们用M[i]表示第i月有多少天。
这里要注意的是不用单独判闰年,2月29对应的是92200229,而9220是闰年。

构建字符串直接参照代码,最后比较一下即可

代码实现

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
/* -- Basic Headers -- */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>

/* -- STL Iterators -- */
#include <vector>
#include <string>
#include <stack>
#include <queue>

/* -- External Headers -- */
#include <map>
#include <cmath>

/* -- Defined Functions -- */
#define For(a,x,y) for (int a = x; a <= y; ++a)
#define Forw(a,x,y) for (int a = x; a < y; ++a)
#define Bak(a,y,x) for (int a = y; a >= x; --a)

/* -- Defined Words -- */
#define GetMonth(x) ((x / 100) % 100)
#define GetDay(x) (x % 100)
#define GetYear(x) (x / 10000)
#define isFullYear(x) ((GetYear(x) % 400 == 0) || (GetYear(x) % 10 == 0 && GetYear(x) % 4 != 0))

using namespace std;

namespace FastIO {

inline int getint() {
int s = 0, x = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') x = -1;
ch = getchar();
}
while (isdigit(ch)) {
s = s * 10 + ch - '0';
ch = getchar();
}
return s * x;
}
inline void __basic_putint(int x) {
if (x < 0) {
x = -x;
putchar('-');
}
if (x >= 10) __basic_putint(x / 10);
putchar(x % 10 + '0');
}

inline void putint(int x, char external) {
__basic_putint(x);
putchar(external);
}
}


namespace Solution {
const int M[12 + 1] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int start;
int endd;
int ans;
}

signed main() {
#define HANDWER_FILE
#ifndef HANDWER_FILE
freopen("testdata.in", "r", stdin);
freopen("testdata.out", "w", stdout);
#endif
using namespace Solution;
cin >> start;
cin >> endd;
for (int i = 1; i <= 12; ++i) {
for (int j = 1; j <= M[i]; ++j) {
int now = 0;
now += j;
now += i * 100;
now += 10000000 * (j % 10);
now += 1000000 * (j / 10);
now += 100000 * (i % 10);
now += 10000 * (i / 10);
if (start <= now && now <= endd) ++ans;
}
}
FastIO::putint(ans, '\n');
return 0;
}