题目一

任务描述

本关任务:蔡若坤和郑付商量决定从2022年6月7日起开始三天练体能两天考试,这个制度一直延续下去,问在以后的某一天中是练体能还是考试。

编程要求

根据提示,在右侧编辑器补充代码,根据输入的日期计算出考试还是练体能。
注意:自行编写函数,不要使用Python标准库或第三方库

测试说明

平台会对你编写的代码进行测试:测试输入:

2035 6 13

预期输出:

考试

开始你的任务吧,祝你成功!


题目一解答

题目条件很简单,从6月7日起,相当于6月7日就是第一天。6.7:体能,6.8:体能,6.9:体能,6.10:考试,6.11:考试,6.12:体能···

思路分析

思路也很简单,算出给定的那天距离6月7日的天数,除以5取余数。

主要的难点在于如何求得相差的天数。用给的例子来说,2035年6月13日,从2022年到2034年,累加每年的天数;再算出6月13日是这一年的第几天,最后减去6月7日是2022年第几天。

现在开始动手写代码吧。

编写程序

观察所给的初始代码

def exersize_or_exam(y, m, d):
    ######### Begin #########



    #########  End  #########
    return result

def get_ymd(date):
    ######### Begin #########


    #########  End  #########
    return y, m, d

def main():
    date = input('')
    y, m, d = get_ymd(date)
    result = exersize_or_exam(y, m, d)
    print(result)


main()

定义了三个函数,main() 函数是不需要编写的,容易看出get_ymd(date) 的功能是把输入的日期字符串转化为年月日分别赋值给y、m、d,再将y、m、d传入exersize_or_exam(y, m, d)得到结果。

get_ymd(date)

利用字符串的split()方法返回一个包含年月日的列表,split()的功能就是使用指定的字符(串)来分割当前的字符串对象,返回一个列表,如果括号内不传参数就默认以空字符分割。空字符包含空格换行符\n制表符\t回车\r等。

def get_ymd(date):
    # 转化为整数方便之后计算
    y, m, d = [int(i) for i in date.split()]

接下来是重头戏exersize_or_exam(y, m, d)

根据之前的思路,先要写一个程序来获取由年相差的天数,在其中还需判断闰年;还需要一个程序判断月份的天数。最后再加上天数

根据思路,可以初步写出一个框架

def exersize_or_exam(y, m, d):

    # 定义一个列表来储存每个月的天数
    months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    # 定义一个列表来储存结果
    choices = ['体能','体能','体能','考试','考试']
    # 初始化一个变量来储存相差的天数,6月7日是第158天,以这天为第一天,2022年1月0日就是第-158天
    a = -158
    # 年相差的天数
    
    # 月相差的天数
    
    # 日相差的天数

现在先完成计算年相差的天数

# 从2022年开始遍历到目标年份的前一年,将每年的天数加到a当中
for i in range(2022, y):
    # 判断是否是闰年,闰年加366,否则加365
    # 年份4的倍数且不是100的倍数或者是400的倍数
    if (i % 4 == 0 and i % 100 != 0) or i % 400 == 0:
        a += 366
    else:
        a += 365

然后完成计算月相差的天数

# 月相差的天数
# 从第一月到目标月的上一个月,依次将每个月的天数加到a中
for j in range(m - 1):
    a += months[j]

# 如果目标年份是闰年且目标月份在二月之后,则还要把二月份的天数加上一天
if ((y % 4 == 0 and y % 100 != 0) or y % 400 == 0) and m >= 3:
    a += 1

完成日相差的天数

# 最后加上日
a += d

最后获取这天的安排,返回结果

# 获取这一天的安排
# 注意:列表索引从0开始
result = choices[a%5 - 1]

完整代码如下:

def exersize_or_exam(y, m, d):
    months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    choices = ['体能', '体能', '体能', '考试', '考试']
    # 初始化一个变量来储存相差的天数,6月7日是第158天,以这天为第一天,2022年1月0日就是第-158天
    a = -158
    
    # 年相差的天数
    # 从2022年开始遍历到目标年份的前一年,将每年的天数加到a当中
    for i in range(2022, y):
        # 判断是否是闰年,闰年加366,否则加365
        # 年份4的倍数且不是100的倍数或者是400的倍数
        if (i % 4 == 0 and i % 100 != 0) or i % 400 == 0:
            a += 366
        else:
            a += 365

    # 月相差的天数
    # 从第一月到目标月的上一个月,依次将每个月的天数加到a中
    for j in range(m - 1):
        a += months[j]

    # 如果目标年份是闰年且目标月份在二月之后,则还要把二月份的天数加上一天
    if ((y % 4 == 0 and y % 100 != 0) or y % 400 == 0) and m >= 3:
        a += 1
    
    # 日相差的天数
    # 最后加上日
    a += d

    # 获取这一天的安排
    # 注意:列表索引从0开始
    result = choices[a%5 - 1]

    return result


def get_ymd(date):
    # 转化为整数方便之后计算
    y, m, d = [int(i) for i in date.split()]
    return y, m, d


def main():
    date = input('')
    y, m, d = get_ymd(date)
    result = exersize_or_exam(y, m, d)
    print(result)


main()

这道题难度不高,易错点在于闰年的判断,还有参考日期的选取,该不该算第一天,该减多少。

对于这种问题其实只需要把代码写出来,在本地IDE中丢几个数据进去验证就能确定到底该加多少减多少。