深耕专业教研,探索前沿技术
信息技术来源:Z20+名校联盟2026届高三第三次学情诊断

第 15 题

答案与解析

第(1)小题

参考答案

[3,1]

10:25 到 11:20 涉及 10~11、11~12 两个使用时段。信号 0、1 都表示当前时段无人,信号 2 表示当前有人。

使用时段 按图 a 判断 分配结果
10~11 1、2、4 号座位均为红灯,只有 3 号座位为黄灯,当前可用;其下一时段为红灯,连续空闲时段数为 1 3 号座位
11~12 3 号座位已不能继续使用,需重新选择;此时只有 1 号座位空闲 1 号座位

按使用时段顺序记录,安排为 [3,1]。

第(2)①小题

参考答案

12

程序分析

h.append([0]*n)

在信号表末尾增加一行 n 个 0,作为统计的边界行。这一行位于原有时段之后。

for i in range(len(h)-2,-1,-1):
    for j in range(n):
        if h[i][j]==0 or h[i][j]==1:
            h[i][j]=h[i-1][j]+1
        else:
            h[i][j]=0    #语句1

i 从原表最后一行倒序遍历到第 0 行,新增边界行不参与循环;j 遍历各座位。信号 0、1 都表示当前座位无人,进入加框语句;信号 2 表示当前有人,执行语句1,将统计值记为 0。加框语句试图累计连续空闲时段,但题目已指出其中有误,其累计方向需在②中修正。

语句1位于 else 分支,只有当前信号既不是 0 也不是 1,即为红灯信号 2 时才执行。按座位列统计图 a 中的红灯数:

座位号 红灯时段数
1 4
2 4
3 1
4 3

共执行 4+4+1+3=12 次。加框处虽有错误,但它只改写当前 h[i][j];遍历到某个位置时,该位置仍是原始信号,所以不影响该位置是否进入 else 分支。

第(2)②小题

参考答案

h[i][j]=h[i+1][j]+1

共用程序分析见第(2)①小题。

填空分析

h[i][j]=h[i-1][j]+1

空位统计表要记录“从当前时段开始,向后连续空闲的时段数”。当前信号为 0 或 1 时,本时段可用,连续空闲数应为下一时段的连续空闲数加 1。

循环从最后一个时段向前处理,所以 h[i+1][j] 已经完成统计,而 h[i-1][j] 对应更早时段,尚未处理,不能作为向后的累计依据。加框处应改为:

h[i][j]=h[i+1][j]+1

例如,1 号座位 13~14 时段有人,统计值为 0;12~13 时段空闲,得到 0+1=1;11~12 时段也空闲,得到 1+1=2,与图 b 一致。末尾补入的全 0 行使最后一个开放时段在空闲时得到 0+1=1,不会把关门后的时段算入。

第(3)小题

参考答案
  1. td=t2-t1

  2. d[i][m]==0

  3. i+=1

程序分析

h=creat(y,st,ed,n)    #获取自修室指示灯信号表
d=trans(h)    #将指示灯信号表转化为空位统计表

先调用第14题的 creat 得到信号表,再使用第(2)题修正后的 trans 得到空位统计表 d。d[i][j] 表示从第 i 行对应时段开始,j+1 号座位连续空闲的时段数;行号 0 对应开门时段 st~st+1。

t1=int(at[:2]) ; t2=int(pt[:2])+1
tot=0 ; res=[]    #数组res存储读者各使用时段的座位号
①
flag=True ; i=t1-st
while i<t2-st:
    if tot==0:
        ...
    else:
        ...

t1 取到达时刻的小时数,t2 按题给代码取离开时刻的小时数加1。i 从到达时段对应的行号 t1-st 开始,在 i<t2-st 时继续处理。循环按 tot 是否为0分成两步:为0时选择座位,否则为当前时段分配已选座位。res 保存分配结果,flag 初值为 True。

if tot==0:
    m=0
    for j in range(1,n):
        if d[i][j]>d[i][m]:
            m=j
    if ②:
        flag=False
        break
    tot=d[i][m]

tot 为 0 时重新选择座位。m 先取最小列号 0,j 从小到大扫描,只有发现更大的连续空闲数才更新 m,因此相同时保留较小座位号。扫描结束,m 对应当前时段连续空闲数最大的座位。若满足失败条件,则标记并退出;否则把该座位的连续空闲数赋给 tot,下一轮进入分配分支。

else:
    res.append(m+1)
    if tot>=td:
        d[i][m]-=td
    else:
        d[i][m]-=tot
    tot-=1 ; td-=1
    ③

res 追加 m+1,将列下标转换为座位号。接着从当前统计值中减去 tot、td 中较小的一个,表示本段安排占用的连续时段数。每安排一个时段,tot 和 td 都减 1:tot 表示当前座位还可连续使用的时段数,td 表示读者尚未完成分配的时段数。当前座位用完后,tot 变为 0,程序在下一待安排时段重新选座。

if flag==False:
    print("座位安排失败!")
else:
    print(t1,"~",t2,"中各时段座位安排:",res)

若中途标记失败,输出失败提示;否则输出按时段顺序保存的座位号列表。

填空分析

①

td 表示尚需安排的时段数,初值应为本次全部使用时段数。根据题给折算,时段起点从 t1 到 t2-1,共 t2-t1 个,因此填写:

td=t2-t1

本题示例均为非整点离开。若整点离开且不占用离开后的时段,固定语句 t2=int(pt[:2])+1 会多计一个时段;这属于题面时间折算的边界问题,不能只靠本题三个空缺消除。

②

m 已指向当前时段连续空闲数最大的座位。若最大值 d[i][m] 仍为 0,说明当前所有座位都不可用,应分配失败;只要大于 0,就可以先安排该座位,之后再按规则处理剩余时段。因此填写:

d[i][m]==0

③

else 分支已经为当前时段追加了一个座位号,并把两个剩余时段数各减 1,接下来应转到下一时段,填写:

i+=1

重新选座的分支只确定座位,没有完成当前时段的安排,所以不能在那里增加 i。