- 专栏
- 《蓝桥杯题目》
【问题描述】
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在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
【题目解析】
1、日期都在1960年1月1日至2059年12月31日。说明[60,99]都是19XX,[00,59]都是20XX。
2、输入格式是"02/03/04",这个格式可能是2002年03月04日、2004年02月03日或2004年03月02日。短短一句话,就挖了三个大坑!!!
- 将输入换成AA/BB/CC,那么这个日期就只有,AA年BB月CC日,CC年AA月BB日以及CC年BB月AA日,而不是三个数的排列组合。说明年只能取AA和CC,月份只能取AA和BB。
- 题目列举的恰好是合法日期,而测试的数据存在变化后不合法的情况,即月份要满足[0,12],天数要先判断闰年还是平年。
- AA,BB,CC没有说是不同的数字,所有当他们取相同的数时,组合后的日期就存在重复,所以需要进行去重处理。
总结一下解题的步骤:
- 遍历所有的组合情况
- 日期是否合法(闰年平年判断,月份和天数不能为0,AA BB CC只能取一次)
- 输出日期
【代码实现】
x,y,z=map(int,input().split("/"))
month=[0,31,28,31,30,31,30,31,31,30,31,30,31]
ymd=set() #空集合,去重效果,存日期
Y=[x,0,z]
M=[x,y,0]
D=[x,y,z]
for n in range(len(Y)): #年
for m in range(len(M)): #月
for k in range(len(D)): #日
if (n!=m)and (n!=k)and(m!=k)and(n!=1)and(m!=2):
#年份判断19or20
if Y[n]>=60:
year=1900+Y[n]
else:
year=2000+Y[n]
#月、日是否合法
if (M[m]>=13)or(M[m]==0)or(D[k]==0):
continue
if (M[m]==2):
#判断是否为闰年
#能被4整除却不能被100整除或能被400整除的年份就是闰年
if ((year%4==0)and (year%100!=0)) or (year%400==0):
if D[k]>29:
continue
else:
if D[k]>28:
continue
else:
if D[k]>month[D[m]]:
continue
#组装成一个数并放进集合
ymd.add(year*10000+M[m]*100+D[k])
ymd=list(ymd)#排序(升序)
ymd.sort()
for i in range(len(ymd)):
H=str(ymd[i])
print(H[:4],end="-")
print(H[4:6],end="-")
print(H[6:8])
【运行结果】