第 15 题
答案与解析
第(1)小题
1,2,4,3
每份蛋糕完成制作后还需2分钟拍照登记,因此应把这2分钟计入提交前的总耗时。4号制作时间改为13分钟后,1至5号的总耗时依次为30、15、40、15、30分钟。
选择顺序1、2、4、3,从18:00开始连续制作并登记:
| 蛋糕编号 | 制作及登记总耗时 | 提交时刻 | 截止时间 |
|---|---|---|---|
| 1 | 30分钟 | 18:30 | 18:30 |
| 2 | 15分钟 | 18:45 | 19:00 |
| 4 | 15分钟 | 19:00 | 19:00 |
| 3 | 40分钟 | 19:40 | 19:40 |
这4份均能按时提交。若完成全部5份,共需30+15+40+15+30=130分钟,而这5份中最晚截止时间为19:40,距18:00只有100分钟,因此无法全部按时提交。已有4份的可行安排,且5份不可能,故最多完成4份。
第(2)小题
A
C
程序分析
def Sort(a):
for i in range(len(a)-1):
for j in range():
if a[j][2]>a[j+1][2]:
a[j],a[j+1]=a[j+1],a[j]
return a外层循环执行 len(a)-1 轮。每次内层循环比较相邻的 a[j] 与 a[j+1],下标2对应制作所需时间;左侧耗时较大时交换,使较小的数向左、较大的数向右移动。要得到完整的升序序列,内层范围还必须保证未排好位置的元素能够继续移动,不能只检查相邻下标是否越界。
填空分析
range(...) 中的参数
第(3)小题
task[i][2]+2
a[j][0]>task[i][1] or task[i][2]<=0
[task[i][1]+1,a[j][1]]
程序分析
for i in range(n):
task[i][1]=int(task[i][1][:2])*60+int(task[i][1][3:])
task[i][2]=①
task = Sort(task)预处理把“时:分”转换成从0:00起累计的分钟数,便于与时间区间的端点比较。task[i][2]在空①处更新后,Sort(task)按这一列升序排列,因此后续依次检查耗时较短的任务。
a=[[1081,1320]] #18:01和22:00分别转换为分钟
ans=0
for i in range(n):
...a 初始包含区间[1081,1320],对应18:00之后至22:00的240个一分钟时段;区间端点均计入长度,1081可理解为18:00至18:01这一分钟的结束刻度。ans 初值为0,外层循环按排序后的顺序逐项检查蛋糕任务。
t=j=0
while j<len(a) and a[j][1]<=task[i][1]:
t+=a[j][1]-a[j][0]+1
j+=1
if j<len(a) and a[j][0]<=task[i][1]:
t+=task[i][1]-a[j][0]+1j 从0开始扫描区间。若一个区间的右端不超过当前截止时间,就把其完整长度 a[j][1]-a[j][0]+1 加到 t;遇到右端超过截止时间的区间后,若左端仍不超过截止时间,则只加入左端到截止时间这一段的长度。由这种累加方式可知,a 需要保存尚未占用的时间区间,并按时间先后排列,t 统计当前截止时间以内共有多少空闲分钟。
if t>=task[i][2]:
ans += 1
b=[]
for j in range(len(a)-1,-1,-1):
if ②:
b.append(a[j])
elif a[j][1]<=task[i][1]:
t=a[j][1]-a[j][0]+1
if t>task[i][2]:
a[j][1]=a[j][1]-task[i][2]
b.append(a[j])
task[i][2]-=t
else:
t=task[i][1]-a[j][0]+1
b.append(③)
if t>task[i][2]:
a[j][1]=task[i][1]-task[i][2]
b.append(a[j])
task[i][2]-=t
a=b[::-1]当 t 不少于当前任务所需时间时,ans 加1,并开始从 a 的末尾向前扣除占用时间。b 用来收集扣除后保留的空闲区间,逆序扫描使程序优先使用截止时间附近较晚的空闲时段。
通过空②的区间直接加入 b;其余区间再按截止时间的位置分类。elif 对应整个区间都在截止时间以内:此时重新用 t 保存该区间长度。若区间比剩余需求长,就缩短右端并保留前段;否则整个区间被使用,不再加入 b。随后减去 t,使 task[i][2] 转为当前任务还需分配的时间。区间有富余时,这个值会变成负数,也应视为已经分配完毕。
最后的 else 处理截止时间位于区间内部的情况:t 只取左端至截止时间的长度,空③负责保存不能用于当前任务的后段;若截止时间以前的部分仍有富余,再缩短原区间右端并保留前段。最后同样扣减剩余需求。b 按从晚到早的次序收集,a=b[::-1] 将其恢复为从早到晚,供下一份蛋糕继续扫描。
填空分析
①
task[i][2] 原来只包含制作时间,题目要求完成后另花2分钟拍照登记才能提交。因此总占用时间应为原制作时间加2,填写 task[i][2]+2。
②
执行 b.append(a[j]) 表示当前空闲区间完整保留、不再扣除。需要覆盖两种情况:一是 a[j][0]>task[i][1],整个区间都在当前任务截止时间之后,不能用于该任务;二是 task[i][2]<=0,当前任务已经分配完毕,剩余空闲区间都应保留。两种情况任一成立即可,因此填写 a[j][0]>task[i][1] or task[i][2]<=0。
这里必须包含小于0的情况,因为前面按整个可用段长度扣减,分配完成后剩余需求可能为负数。左端恰好等于截止时间时仍有1分钟可用,所以第一个条件使用严格大于。
③
进入最后的 else 时,当前任务仍需分配,区间左端不晚于截止时间,而右端晚于截止时间,因此该区间跨越截止时间。用于当前任务的部分最多到截止时间为止,后段应完整保留。由于区间采用两端包含的整数分钟刻度,后段从 task[i][1]+1 开始,到原右端 a[j][1] 结束,所以填 [task[i][1]+1,a[j][1]]。此时尚未执行下方对原右端的修改,能够保留正确的后段终点。
问题反馈
解析有疑问或显示异常?请先复制题目信息,再打开反馈表单填写。
题目编号:2026_05_G3_beidouxingmeng_q015
