avatar

蓝桥杯 历届真题 日期问题

本文由Hobee原创,并仅在本站发表,仅供各位小伙伴学习交流使用。

为避免不必要的纠纷,本文禁止以任何形式转载,谢谢配合。

如有问题请通过评论区或邮件联系作者。

本文封面源于蓝桥杯官网

题目

原题传送门

问题描述

小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。

给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

输入格式

一个日期,格式是”AA/BB/CC”。 (0 <= A, B, C <= 9)

输出格式

输出若干个不相同的日期,每个日期一行,格式是”YYYY-MM-DD”。多个日期按从早到晚排列。

样例输入

02/03/04

样例输出

2002-03-04

2004-02-03

2004-03-02

数据规模和约定

峰值内存消耗(含虚拟机) < 256M

CPU消耗 < 1000ms

思路

读完题后其实思路还是蛮清晰的,不过就是 读入->判断是否合法->输出 就大功告成了。

读入数据Python有split()方法,很好搞定。判断的话分三种情况,按题目所说将不同的情况分别进行判断,合法的用列表记录下来,不合法的就跳过。为了保证日期不重复,就在三种情况都判断完之后,将列表转换为集合进行去重。最后按顺序输出就再转换回列表并sort一下。这里因为日期是符合字典序的顺序排列的,所以可以直接sort,而不用自己再写一个排序函数了。

不过需要注意,既然是处理日期,就要判断某个月是30天还是31天,是不是闰年也要特殊判断。我们在补全年份的时候要注意,由于给定的日期是有范围的,所以要根据不同的情况加上不同的前缀。大于等于60的时候补‘19’,小于‘60’的时候补‘20’.

代码

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
def year(y):
if y%4 == 0:
if y%100 == 0:
if y%400 == 0:
return 1
else:
return 0
else:
return 1
else:
return 0

def check(y,m,d):
if m == '00' or d == '00':
return -1
if int(m)>12:
return -1
elif int(m) in [1,3,5,7,8,10,12]:
if int(d) > 31:
return -1
if int(y) >= 60:
l.append('19'+y+'-'+m+'-'+d)
else:
l.append('20'+y+'-'+m+'-'+d)
elif int(m) in [4,6,9,11]:
if int(d) > 30:
return -1
if int(y) >= 60:
l.append('19'+y+'-'+m+'-'+d)
else:
l.append('20'+y+'-'+m+'-'+d)
else:
if int(y) >= 60:
if year(int('19'+y)) and int(d)<=29:
l.append('19'+y+'-'+m+'-'+d)
elif not year(int('19'+y)) and int(d)<=28:
l.append('19'+y+'-'+m+'-'+d)
else:
return 0
else:
if year(int('20'+y)) and int(d)<=29:
l.append('20'+y+'-'+m+'-'+d)
elif not year(int('20'+y)) and int(d)<=28:
l.append('20'+y+'-'+m+'-'+d)
else:
return 0
return 0

a,b,c = list(input().split('/'))
l = []
check(a,b,c)
check(c,a,b)
check(c,b,a)
l = list(set(l))
l.sort()
for c in l:
print(c)

避坑

这个题看上去十分简单,思路也很清晰,但往往这样的题都是笑里藏刀,果不其然,这题的数据确实有点东西。我在提交之后只得了87分,也就是差一个点没有过,但我实在想不到哪里出问题了,在看了好多题解之后(csdn上好多博主真的只给代码,不给解释,我看着就头大。虽然我这个代码没有解释,但思路和避坑足够你a题了),终于明白了问题所在:‘00’。‘00’这个数据只有在用作年份的时候合法,比如‘2000’年,但用作月份和日子都是不合法的。而我之前的程序对‘00’没有特殊判断,所以会输出3个日期,这显然是不合理的。

于是我赶紧将check函数第一行加上了对‘00’的判断,于是AC了。

文章作者: hobee
文章链接: https://hobeedzc.github.io/2020/04/18/%E8%93%9D%E6%A1%A5%E6%9D%AF%E5%8E%86%E5%B1%8A%E7%9C%9F%E9%A2%98%20%E6%97%A5%E6%9C%9F%E9%97%AE%E9%A2%98/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hobee's Blog

评论