1. 问题描述:
小蓝每天都锻炼身体。正常情况下,小蓝每天跑1千米。如果某天是周一或者月初(1日),为了激励自己,小蓝要跑2千米。如果同时是周一或月初,小蓝也是跑2千米。小蓝跑步已经坚持了很长时间,从2000年1月1日周六(含)到2020年10月1日周四(含)。请问这段时间小蓝总共跑步多少千米?
2. 思路分析:
① 一个比较容易想到的做法是像翻日历那样,对星期、月份、年份、天数进行累加,所以我们首先需要声明四个变量,分别是年份、月份、天数,星期,循环的一开始对于当前的天数或者是星期判断看是否满足当前的天数等于1或者是当前是星期一,如果是则累加2,不是则累加1,并且判断当前的日期是否是2020年10月1日,如果是那么退出循环,不是则需要天数加1,星期加1,判断当前加1之后的天数是否超出了当前月份的天数,这里可以使用一个方法传递当前年份与月份用来计算当前的天数是否大于了整个月的天数,如果大于了那么更新天数为1,并且月份加1,最后判断出当前的月份是否超过了12,如果超过了那么年份就要加1了。整个过程的重点是先累加天数与星期(进行日期与星期的更新),然后判断天数是否是超过这个月的最大的天数,如果是则需要更新当前的天数与月份,最后根据月份是否超过12来更新年份,整个过程还是很好理解的,涉及到的细节比较多一点。并且我们可以使用print语句将循环中的每一天都写入到txt文件中,通过比较最终的日期是否正确来调整自己的代码
② 第二种思路是使用python中的date模块中的date方法,通过date方法构造一个包含年月日的最简单的日期,然后通过timedelta方法指定两个日期相差的间隔,通过循环(起始时间小于结束时间为循环条件)累加天数即可解决这个问题,所以使用python的api会非常快速而准确地解决这个问题
3. 代码如下:
模拟:
from typing import List
# 判断是否是闰年
def isLeap(year: int):
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def days(year: int, month: int, months: List[List[int]]):
return months[isLeap(year)][month]
if __name__ == '__main__':
year, month, day, week = 2000, 1, 1, 6
# 使用二维列表会更容易处理, 根据判断出是否是闰年就可以知道当前月份的天数
months = [[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]]
# 设置flag这样最后一天才可以累计在循环中
res, flag = 0, 1
# 注意如果路径为一个反斜杠那么路径前面需要加上一个字母r
file = open(r"C:\Users\data.txt", "w+")
while flag:
# 使用print语句将日期写入到文件中用来校验代码是否正确
print("{}年{}月{}日是星期{}".format(year, month, day, week), file=file)
if year == 2020 and month == 10 and day == 1: flag = 0
if day == 1 or week == 1:
res += 2
else:
res += 1
# 先累加日期和星期, 当日期不满足的时候调整日期与月份即可
week = (week + 1) % 7
day += 1
if day > days(year, month - 1, months):
day = 1
month += 1
if month == 13:
year += 1
month = 1
# 如果未使用with来打开文件这个时候需要手动关闭文件
file.close()
print(res)
api:
from datetime import *
if __name__ == '__main__':
# 声明一个包含年月日的简单日期
start = date(2000, 1, 1)
end = date(2020, 10, 1)
days = timedelta(days=1)
res = 0
print(type(start))
while start <= end:
if start.day == 1 or start.weekday() == 0:
res += 2
else:
res += 1
start += days
print(res)