hihocoder 1148 — 2月29日
16 Oct 20161 描述
给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期)。
只有闰年有2月29日,满足以下一个条件的年份为闰年:
-
年份能被4整除但不能被100整除
-
年份能被400整除
2 输入
第一行为一个整数T,表示数据组数。
之后每组数据包含两行。每一行格式为”month day, year”,表示一个日期。month为{“January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November” , “December”}中的一个字符串。day与year为两个数字。
数据保证给定的日期合法且第一个日期早于或等于第二个日期。
3 输出
对于每组数据输出一行,形如”Case #X: Y”。X为数据组数,从1开始,Y为答案。
4 实现
import re
months = ["January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"]
mdict = dict(zip(months, xrange(1, 13)))
def parse(s, mdict):
mm, dd, yy = re.compile(r"^(\w{3,9})\s(\d{1,2}),\s(\d{4,10})$").match(s).groups()
yy = int(yy)
mm = mdict[mm]
dd = int(dd)
return (yy, mm, dd)
def is_leapYear(x):
return x % 400 == 0 if x % 100 == 0 else x % 4 == 0
def nlpy(y): # 找到离这个年份最近的下一个闰年
y = y / 4 * 4 + 4 # 在python2中: 普通除(/)= 地板除(//)
while not is_leapYear(y):
y += 4
return y
def nextLeap(t): # 找到离该日期最近的下一个 2月29日
y = t[0]
if not is_leapYear(y):
return (nlpy(y), 2, 29)
elif t <= (y, 2, 29):
return (y, 2, 29)
else:
return (nlpy(y), 2, 29)
def next(y, d): # 返回离y最近的下一个d倍数字
return y if y % d == 0 else y / d * d + d
def countYear(y1, y2): # 计算两个年份之间有多少个闰年,采用交并集的思想
c4 = (y2 - y1) / 4
c100 = (next(y2, 100) - next(y1, 100)) / 100
c400 = (next(y2, 400) - next(y1, 400)) / 400
return c4 - c100 + c400
while True:
try:
couple = int(raw_input().strip())
for i in xrange(couple):
t1 = parse(raw_input().strip(), mdict)
t2 = parse(raw_input().strip(), mdict)
t2 = (t2[0], t2[1], t2[2] + 1)
t1 = nextLeap(t1)
t2 = nextLeap(t2)
print('Case #%d: %d' % (i + 1, countYear(t1[0], t2[0])))
except EOFError:
break
if __name__ == '__main__': # 原来hihocoder不用一直循环输入,只做一次测试输入就行
couple = int(raw_input().strip())
for ci in xrange(couple):
t1 = parse(raw_input().strip(), mdict)
t2 = parse(raw_input().strip(), mdict)
t2 = (t2[0], t2[1], t2[2] + 1)
t1 = nextLeap(t1)
t2 = nextLeap(t2)
print('Case #%d: %d' % (ci + 1, countYear(t1[0], t2[0])))
5 总结
- python2.7.6
print()
输出(a tuple) - python2.7.6应该尽量用
xrange
- python2.7.6的普通除(/)= 地板除(//)
- 原来hihocoder不用一直循环输入,只做一次测试输入就行
- 简介的分支语句实现
x % 400 == 0 if x % 100 == 0 else x % 4 == 0
re.sub()
替换可以写在re.split()
函数参数里面传入:re.split('\s+', re.sub(',', '', aString))
(其返回list
)re.compile(r"^(\w*) (\d*), (\d*)$").match(aString).groups()
更优雅(其返回tuple
)- 应该先思考,再下笔!