ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

手机App防沉迷系统

手机App防沉迷系统 一、题目题目描述智能手机方便了我们生活的同时也侵占了我们不少的时间。“手机App防沉迷系统”能够让我们每天合理地规划手机App使用时间在正确的时间做正确的事。它的大概原理是这样的在一天24小时内可以注册每个App的允许使用时段一个时间段只能使用一个AppApp有优先级数值越高优先级越高。注册使用时段时如果高优先级的App时间和低优先级的时段有冲突则系统会自动注销低优先级的时段如果App的优先级相同则后添加的App不能注册。请编程实现根据输入数据注册App并根据输入的时间点返回时间点使用的App名称如果该时间点没有注册任何App请返回字符串“NA”。输入描述第一行表示注册的App数量 NN ≤ 100第二部分包括 N 行每行表示一条App注册数据最后一行输入一个时间点程序即返回该时间点使用的App2App1 1 09:00 10:00App2 2 11:00 11:3009:30数据说明如下N行注册数据以空格分隔四项数依次表示App名称、优先级、起始时间、结束时间优先级1~5数字越大优先级越高时间格式 HH:MM小时和分钟都是两位不足两位前面补0起始时间需小于结束时间否则注册不上注册信息中的时间段包含起始时间点不包含结束时间点输出描述输出一个字符串表示App名称或NA表示空闲时间示例1输入1App1 1 09:00 10:0009:30123输出App11说明App1注册在9点到10点间9点半可用的应用名是App1示例2输入2App1 1 09:00 10:00App2 2 09:10 09:3009:201234输出App21说明APP1和App2的时段有冲突App2优先级高注册App2之后App1自动注销因此输出App2。示例3输入2App1 1 09:00 10:00App2 2 09:10 09:3009:501234输出NA二、代码classApp:定义App类用于存储App的相关信息def__init__(self,name,priority,start_time,end_time):self.namename# App名称self.prioritypriority# App优先级self.start_timestart_time# App允许使用的起始时间以分钟为单位self.end_timeend_time# App允许使用的结束时间以分钟为单位defconvert_time(time_str): 时间转换函数将时间字符串转换为以分钟为单位的整数 :param time_str: 时间字符串格式为小时:分钟 :return: 转换后的分钟数 hours,minutesmap(int,time_str.split(:))# 将时间字符串按照:分割并转换为整数returnhours*60minutes# 将小时和分钟转换为分钟defmain():nint(input())# 读取App数量apps[]# 创建App列表用于存储所有Appfor_inrange(n):# 循环读取每个App的信息并创建App对象添加到列表中app_name,app_priority,app_start_time,app_end_timeinput().split()app_priorityint(app_priority)app_start_timeconvert_time(app_start_time)app_end_timeconvert_time(app_end_time)apps.append(App(app_name,app_priority,app_start_time,app_end_time))query_timeconvert_time(input())# 读取查询时间并转换为分钟app_at_timeNA# 初始化查询时间对应的App名称为NA# 创建已注册App列表registered_apps[]forappinapps:ifapp.start_timeapp.end_time:continue# 如果起始时间不小于结束时间则跳过# 遍历已注册的App列表检查时间冲突foriinrange(len(registered_apps)-1,-1,-1):registeredregistered_apps[i]# 如果存在时间冲突ifmax(app.start_time,registered.start_time)min(app.end_time,registered.end_time):# 如果当前App的优先级高于已注册App的优先级ifapp.priorityregistered.priority:registered_apps.pop(i)# 注销低优先级的Appelse:continue# 如果优先级不高继续检查下一个已注册App# 将当前App添加到已注册App列表中registered_apps.append(app)# 遍历已注册App列表找到查询时间对应的Appforappinregistered_apps:ifquery_timeapp.start_timeandquery_timeapp.end_time:app_at_timeapp.name# 更新查询时间对应的App名称break# 找到后退出循环print(app_at_time)# 输出查询时间对应的App名称if__name____main__:main()说明1、for _ in range(n):中的下划线_是一个常用的Python约定表示一个临时变量在循环中不会被使用。这里我们只需要循环n次而不关心循环变量的值。2、代码实现了App防沉迷系统的核心逻辑按优先级处理时间冲突高优先级App会覆盖低优先级App的注册时段。3、时间处理将HH:MM格式的时间转换为分钟数便于比较和计算。4、冲突检测使用max(app.start_time, registered.start_time) min(app.end_time, registered.end_time)判断两个时间段是否有重叠。三、range() 函数详解在上面的代码中我们使用了for _ in range(n):来循环读取n个 App 的信息。range()是 Python 中一个非常基础且重要的内置函数用于生成一个整数序列。1. 基本语法range()函数有三种调用形式range(stop)生成从 0 到stop-1的整数序列。foriinrange(5):print(i)# 输出0, 1, 2, 3, 4range(start, stop)生成从start到stop-1的整数序列。foriinrange(2,6):print(i)# 输出2, 3, 4, 5range(start, stop, step)生成从start到stop-1步长为step的整数序列。foriinrange(0,10,2):print(i)# 输出0, 2, 4, 6, 82. 在本题中的应用在我们的代码中for_inrange(n):# 读取每个 App 的信息n是用户输入的 App 数量。range(n)生成序列0, 1, 2, ..., n-1循环会执行n次。下划线_是一个约定俗成的变量名表示我们在循环中不需要使用这个循环变量即不需要用到i的值我们只关心循环执行的次数。3. 重要特性惰性求值range()返回的是一个“range 对象”而不是一个列表。它只在需要时才生成值节省内存。不可变range 对象是不可变的序列。支持索引可以像列表一样使用索引访问。rrange(5,10)print(r[0])# 输出5print(r[-1])# 输出94. 常见用途固定次数的循环for i in range(10):生成索引遍历列表时同时获取索引和值for i in range(len(lst)):逆序循环for i in range(10, 0, -1):生成数字列表list(range(5))得到[0, 1, 2, 3, 4]5. 注意事项range()的参数必须是整数。stop值不包含在序列中左闭右开区间。如果start stop且step 0或者start stop且step 0则 range 对象为空。理解range()函数对于编写 Python 循环至关重要它是处理重复任务和控制流程的基础工具。6. 代码中range(len(registered_apps) - 1, -1, -1)的解析在本题的冲突检测代码中有这样一行foriinrange(len(registered_apps)-1,-1,-1):这行代码使用了range()函数的第三种形式range(start, stop, step)并且实现了逆序遍历列表的功能。下面详细解析参数含义start len(registered_apps) - 1起始索引是列表最后一个元素的下标。stop -1停止索引是 -1不包含在序列中。step -1步长为 -1表示每次递减 1。生成的序列假设registered_apps列表有 3 个元素len(registered_apps) 3那么len(registered_apps) - 1 2range(2, -1, -1)生成的序列是2, 1, 0为什么需要逆序遍历在冲突检测的逻辑中我们需要遍历已注册的 App 列表检查当前 App 与每个已注册 App 是否有时间冲突。如果发现冲突且当前 App 优先级更高我们会从列表中移除pop那个已注册的低优先级 App。关键点如果我们在正向遍历从 0 到 len-1时移除元素列表的索引会发生变化可能导致跳过元素或索引越界。例如# 错误示例正向遍历时移除元素foriinrange(len(lst)):if条件:lst.pop(i)# 移除后后面所有元素的索引都减 1但 i 还在增加会跳过下一个元素解决方案逆序遍历。从最后一个元素开始向前遍历这样即使移除当前元素也不会影响前面尚未遍历到的元素的索引。在本题中的具体作用foriinrange(len(registered_apps)-1,-1,-1):registeredregistered_apps[i]ifmax(app.start_time,registered.start_time)min(app.end_time,registered.end_time):ifapp.priorityregistered.priority:registered_apps.pop(i)# 安全移除因为 i 后面的元素索引更大的已经遍历过了else:continue从后往前检查先检查最近注册的 App列表末尾符合“后添加的 App 不能注册如果优先级相同”的规则。安全移除pop(i)移除元素时不会影响尚未遍历到的、索引更小的元素。效率逆序遍历在需要移除元素时更安全、更直观。其他逆序遍历写法for i in reversed(range(len(registered_apps))):使用reversed()函数可读性更好。for i in range(len(registered_apps)-1, -1, -1):直接使用range()更底层、更明确。理解这种逆序遍历的技巧对于处理需要修改列表的循环场景非常重要。
返回列表