趣学Python算法100例——1.6 打鱼还是晒网

本文介绍了如何使用Python解决一个关于“三天打鱼两天晒网”的周期性问题,通过计算起始日期和终止日期之间的天数差,结合闰年和平年规则,判断在任意一天的状态。
摘要由CSDN通过智能技术生成

1. 问题描述

中国有句俗语叫“三天打鱼两天晒网”。某人从1990年1月1日起便开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。

2. 问题分析

这是一个存在周期的问题,周期内有两种状态:打鱼和晒网;为了确定这两种状态,可以使用起始日期和终止日期之间的天数差值的除以5的余数来判断,余数为1、2、3即为打鱼状态;余数为4、0即为晒网状态。

2.1 问题拓展

题目要求是1990年1月1日开始直至任意终止日期结束,那么可以拓展为从公元后任意日期开始直至任意目标日期结束。

难点在于计算中间的经历的天数,可以分为三段时间计算:

  1. 起始年剩余天数(包括起始日),注意计算前应判断起始年是否为闰年
  2. 间隔年天数,要判断每一年是否为平年还是闰年
  3. 终止年经历天数(包括终止日),注意计算前应判断终止年是否为闰年

判断平年(non-leap year)和闰年(leap year)的计算方法很简单:

  1. 如果年份是整百年份,用年份除以400,没有余数即为闰年,有余数即为平年。
  2. 如果年份不是整百年份,用年份除以4,没有余数即为闰年,有余数即为平年。
    使用布尔运算即可完成判断。

3. 代码示例

# 作者:爱吃肠粉的笨小孩
# 日期:2024年02月22日 20:14
# 知乎:爱吃肠粉的笨小孩

# 1.问题描述
# 中国有句俗语叫“三天打鱼两天晒网”。某人从1990年1月1日起便开始“三天打鱼两天晒网”,
# 问这个人在以后的某一天中是“打鱼”还是“晒网”。

# 先用列表存储平年和闰年的12个月的天数,注意列表序号从0开始(闰年:leap year;平年:non-leap year)
# 大月:1、3、5、7、8、10、12;小月:4、6、9、11;闰月:2

# 判断平年(non-leap year)和闰年(leap year)的计算方法很简单:
# 1. 如果年份是整百年份,用年份除以400,没有余数即为闰年,有余数即为平年。
# 2. 如果年份不是整百年份,用年份除以4,没有余数即为闰年,有余数即为平年。

solar_month = [1, 3, 5, 7, 8, 10, 12]  # 使用列表存储大月月份
lunar_month = [4, 6, 9, 11]  # 使用列表存储小月月份
leap_month = [2]  # 使用列表存储闰月月份
nl_y = [0] * 12  # 建立空列表以存储平年月份天数,元素数量为12,元素值全为0
l_y = [0] * 12  # 建立空列表以存储平年月份天数,元素数量为12,元素值全为0

# 后面根据月份不同替换元素值即可,注意列表起始序号为0!!!!!!!!

for i in solar_month:  # 替换大月月份天数为31天
    nl_y[i - 1] = 31
for i in leap_month:  # 替换闰月月份天数为28天
    nl_y[i - 1] = 28
for i in lunar_month:  # 替换小月月份天数为30天
    nl_y[i - 1] = 30

for i in solar_month:  # 替换大月月份天数为31天
    l_y[i - 1] = 31
for i in leap_month:  # 替换闰月月份天数为29天
    l_y[i - 1] = 29
for i in lunar_month:  # 替换小月月份天数为30天
    l_y[i - 1] = 30

print("平年月为:", nl_y)
print("闰年月为:", l_y)
if __name__ == '__main__':
    # 使用输入函数输入起始和终止日期
    year_start, month_start, day_start = map(int, input("请按顺序输入起始日期的年、月和日,"
                                                        "起始日期为打鱼第一天"
                                                        "数据之间用空格隔开:").split())
    year_end, month_end, day_end = map(int, input("请按顺序输入终止日期的年、月和日,"
                                                  "数据之间用空格隔开:").split())
year_diff = year_end - year_start
year_nl = 0  # 相隔年份中平年数目
year_l = 0  # 相隔年份中闰年数目

for i in range(year_start + 1, year_end):  # 计算间隔年份中平年和闰年的数量
    if (i % 100 != 0 and i % 4 == 0) or (i % 100 == 0 and i % 400 == 0):
        year_l = year_l + 1
        # print(year_l)
    elif (i % 100 != 0 and i % 4 != 0) or (i % 100 == 0 and i % 400 != 0):
        year_nl = year_nl + 1
        # print(year_nl)

print("相隔年份总数为:", year_end - year_start - 1)
print("相隔年份中平年数目为:", year_nl)
print("相隔年份中闰年数目为:", year_l)

days_gap = year_nl * 365 + year_l * 366  # 间隔年天数
print("间隔年天数为:", days_gap)

# 第一年年份天数
days_first_year = 0
if (year_start % 100 != 0 and year_start % 4 == 0) or (year_start % 100 == 0 and year_start % 400 == 0):
    print("起始年份%u为闰年" % year_start)
    for j in range(0, month_start - 1):
        days_first_year = days_first_year + l_y[j]
        # print(days_first_year)
    days_first_year = 366 - day_start - days_first_year + 1  # 天数包括起始日则+1
    print("第一年剩余天数为:", days_first_year)
if (year_start % 100 != 0 and year_start % 4 != 0) or (year_start % 100 == 0 and year_start % 400 != 0):
    print("起始年份%u为平年" % year_start)
    for j in range(0, month_start - 1):
        days_first_year = days_first_year + nl_y[j]
        # print(days_first_year)
    # print("第一年已过月份天数为")
    days_first_year = 365 - day_start - days_first_year + 1  # 天数包括起始日则+1
    print("第一年剩余天数为:", days_first_year)

# 最后一年年年份天数
days_last_year = 0
if (year_end % 100 != 0 and year_end % 4 == 0) or (year_end % 100 == 0 and year_end % 400 == 0):
    print("终止年份%u为闰年" % year_end)
    for j in range(0, month_end - 1):
        days_last_year = days_last_year + l_y[j]
    days_last_year = day_end + days_last_year
    print("最后一年经历的天数为:", days_last_year)
if (year_end % 100 != 0 and year_end % 4 != 0) or (year_end % 100 == 0 and year_end % 400 != 0):
    print("中止年份%u为平年" % year_end)
    for j in range(0, month_end - 1):
        days_last_year = days_last_year + nl_y[j]
    days_last_year = day_end + days_last_year
    print("第一年剩余天数为:", days_first_year)

days_all = days_gap + days_first_year + days_last_year  # 总天数=间隔年份总天数+起始年剩余天数+终止年经历天数
print("起始日期与终止日期之间的天数为(包括起始日和终止日):", days_all)

if days_all % 5 == 1 or days_all % 5 == 2 or days_all % 5 == 3:
    print("%u年%u月%u日" % (year_end, month_end, day_end), "为:打鱼日")
else:
    print("%u年%u月%u日" % (year_end, month_end, day_end), "为:晒网日")

结果示例:

平年月为: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
闰年月为: [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
请按顺序输入起始日期的年、月和日,起始日期为打鱼第一天数据之间用空格隔开:1949 10 1
请按顺序输入终止日期的年、月和日,数据之间用空格隔开:2024 2 24
相隔年份总数为: 74
相隔年份中平年数目为: 56
相隔年份中闰年数目为: 18
间隔年天数为: 27028
起始年份1949为平年
第一年剩余天数为: 92
终止年份2024为闰年
最后一年经历的天数为: 55
起始日期与终止日期之间的天数为(包括起始日和终止日): 27175
2024年2月24日 为:晒网日

以上就是“趣学Python算法100例——1.6 打鱼还是晒网”的全部内容,希望对你有所帮助。

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

二、Python必备开发工具

img

三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

五、Python练习题

检查学习结果。

img

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

img

最后祝大家天天进步!!

上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。

  • 27
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值