题目1 回文日期
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。
因为如果将这个日期按 “yyyymmdd
” 的格式写成一个 8 位数是 20200202
,恰好是一个回文数。
我们称这样的日期是回文日期。
有人表示 20200202
是“千年一遇” 的特殊日子。
对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202
即 2021 年 12 月 2 日。
也有人表示 20200202
并不仅仅是一个回文日期,还是一个 ABABBABA
型的回文日期。
对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA
型的回文日期:21211212
即 2121 年 12 月 12 日。
算不上“千年一遇”,顶多算“千年两遇”。
给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA
型的回文日期各是哪一天。
注意: 本题数据保证一定有解。
注意
下一个回文日期和下一个 ABABBABA
型的回文日期可能是同一天。
ABABBABA
型的回文日期,需要满足 A≠B。
输入格式
输入包含一个八位整数 N,表示日期。
输出格式
输出两行,每行 1 个八位数。
第一行表示下一个回文日期,第二行表示下一个 ABABBABA
型的回文日期。
数据范围
对于所有评测用例,10000101≤N≤89991231,保证 N 是一个合法日期的 8 位数表示。
输入样例:
20200202
输出样例:
20211202
21211212
思路
- 利用
timedelta
遍历天数 ABABBABA
型的回文日期可能与 普通回文日期是同一天,但是一定不会早于普通的回文日期
python代码
from datetime import *
n=int(input())
sep=timedelta(days=1)
nowadays=datetime.strptime(str(n),'%Y%m%d')
flag=False#第一个回文日期是否找到
ans1,ans2=0,0
while True:nowadays+=sepss=str(nowadays.strftime('%Y%m%d'))if ss[:]==ss[::-1] :if not flag:ans1=int(ss)print(ans1)flag=Trueif ss[0]==ss[2]==ss[-1]==ss[-3] and ss[1]==ss[3]==ss[-2]==ss[-4] and flag and ss[0]!=ss[1]: #在已经是回文的前提下ans2=int(ss)print(ans2)break
知识点
蓝桥杯笔记:蓝桥杯备赛笔记(超详细版)
- 日期的格式化处理,不会的话模版中有
题目2 回文日期
在日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。
牛牛习惯用 8 位数字表示一个日期,其中,前 4 位代表年份,接下来 2 位代表月份,最后 2 位代表日期。
显然:一个日期只有一种表示方法,而两个不同的日期的表示方法不会相同。
牛牛认为,一个日期是回文的,当且仅当表示这个日期的 8 位数字是回文的。
现在,牛牛想知道:在他指定的两个日期之间(包含这两个日期本身),有多少个真实存在的日期是回文的。
一个 8 位数字是回文的,当且仅当对于所有的 i(1≤i≤8) 从左向右数的第 i 个数字和第 9−i 个数字(即从右向左数的第 i 个数字)是相同的。
例如:
- 对于 2016 年 11 月 19 日,用 8 位数字 20161119 表示,它不是回文的。
- 对于 2010 年 1 月 2 日,用 8 位数字 20100102 表示,它是回文的。
- 对于 2010 年 10 月 2 日,用 8 位数字 20101002 表示,它不是回文的。
输入格式
输入包括两行,每行包括一个 8 位数字。
第一行表示牛牛指定的起始日期 date1,第二行表示牛牛指定的终止日期 date2。保证 date1 和 date2 都是真实存在的日期,且年份部分一定为 4 位数字,且首位数字不为 0。
保证 date1 一定不晚于 date2。
输出格式
输出共一行,包含一个整数,表示在 date1 和 date2 之间,有多少个日期是回文的。
输入样例:
20110101
20111231
输出样例:
1
思路
思考问题:遍历每一天,判断是否是回文顺序+合法日期,但是直接遍历可能会超时( 1 0 8 10^8 108)
⬇️
只遍历前四位年份,然后构成回文数字,再从回文数字中判断是否在输入范围内+合法日期
python代码
months=[0,31,28,31,30,31,30,31,31,30,31,30,31]
def check(date):year=date//10000month=date//100%100day=date%100if month>12 or month<1 or day>31 or day<1:return Falseif month!=2 and day>months[month]:return Falseif (year%4==0 and year%100!=0) or year%400==0:flag=1else:flag=0if month==2 and day>flag+months[month]:return Falsereturn True start=int(input())
end=int(input())
ans=0
for i in range(1000,10000):date=ix=ifor j in range(4):date=date*10+x%10x//=10if start<=date<=end and check(date):ans+=1
print(ans)
知识点
蓝桥杯笔记:蓝桥杯备赛笔记(超详细版)
- 字符串处理:逐位提取
- 求余,整除的
熟练操作
- 闰年计算