深耕专业教研,探索前沿技术
信息技术来源:2025学年第二学期北斗星盟高三适应性联考

第 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)小题

参考答案
  1. A

  2. 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(...) 中的参数

A

可填。j 从0增加到 len(a)-2-i,扫描下标0至 len(a)-1-i的待排序区间。相邻逆序交换使该区间的最大值逐步向右移动,最终到达右端;下一轮排除这个已经就位的位置。经过 len(a)-1 轮即可升序排列。

B

不可填。range(len(a)-2,i,-1) 不包含 i,漏掉了 a[i] 与 a[i+1] 的比较。例如只有两个元素,耗时依次为2、1时,唯一一轮 i=0,range(0,0,-1) 为空,完全不比较,结果仍为2、1。

C

可填。第 i 轮令 j 从 i 递减到0,把下标 i+1 的新元素依次与左侧元素比较。已有序的前缀中,若新元素较小,就通过相邻交换逐步向左移动;到达正确位置后,其余比较不会破坏前缀顺序。第0轮排好前2项,之后每轮把有序范围扩大1项,最终完成升序排序。

D

不可填。j 从 i 向右扫描,交换只保证较大元素向右移动,不能保证左端第 i 项已是剩余元素中的最小值;下一轮却跳过了这一位置。例如耗时为3、2、1,首轮得到2、1、3,第二轮只比较后两项,最终仍为2、1、3。

第(3)小题

参考答案
  1. task[i][2]+2

  2. a[j][0]>task[i][1] or task[i][2]<=0

  3. [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]+1

j 从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]]。此时尚未执行下方对原右端的修改,能够保留正确的后段终点。