内容正文:
Python程序综合应用填空题
一、综合题
1.(2025·浙江·高考真题)根据机器的负载率对工厂的6台机器(编号0~5)进行监控和调度,调度规则是:每隔1小时采集1次各台机器的负载率(负载率用百分制表示,例如,负载率95%表示为95,机器休息时的负载率为0),负载率超过90的机器都调度休息;如果所有机器负载率都不超过90,则负载率最高的机器休息,若多台机器负载率同为最高,则编号最小的机器休息,休息的机器在休息1小时后再次工作。
请回答下列问题:
(1)若某次采集到0~5号机器的负载率依次为75、85、88、0、88、87,当前处于休息状态的机器编号3,接下来休息的机器编号是 。
(2)实现上述功能的部分Python程序如下,请在划线处填入合适的代码。
n=6 #机器台数
a=[0]*n #列表a长度为n,各元素值均为0
#启动0~4号机器工作,5号机器休息,代码略
while True:
#延时1小时,再采集各机器负载率存入a,a[i]存放i号机器的负载率,代码略
t=0
cnt=0
for i in range(n):
if :
#调度i号机器休息,代码略
cnt+=1
if a[i]>a[t]:
elif a[i]==0:
#调度i号机器工作,代码略
if :
#调度t号机器休息,代码略
2.(2025·浙江·高考真题)某市举行体育赛事活动,n所学校的选手已完成预赛,现计划根据预赛的成绩挑选s名选手参加市决赛。成绩位列所在学校前w名次的选手直接入选,剩余名额按成绩由高到低依次挑选,成绩相同的选手一并入选,选中的选手数一旦达到或超过s名,挑选结束。
现给定所有选手预赛的成绩数据表,每位选手的数据包含学校编号(0~n-1)、选手编号、成绩,成绩数据表已按成绩由高到低排列。编写程序,计算各选手的校内名次,再按上述规则挑选决赛选手,按成绩数据表中的顺序输出选手编号,同时提供查询功能。选手校内名次的计算方法是:若选手所在学校有m人成绩高于该选手,则该选手的名次为m+1。
在图所示的样例中,n、s、w分别为3、8、2,根据图中前3行数据计算出了每位选手的校内名次,进而选出实际入选的9名选手。
学校编号
0
2
2
0
0
2
2
0
1
1
1
1
选手编号
0002
2027
2002
0072
0182
2071
2128
0012
1081
1002
1008
1208
成绩
198
185
183
182
182
177
177
176
175
163
161
161
校内名次
1
1
2
2
2
3
3
4
1
2
3
3
是否入选
True
True
True
True
True
True
True
False
True
True
False
False
请回答下列问题:
(1)对于图所示前4行数据,若s、w分别为5和1,则0号学校入选人数是 。
(2)定义如下search(data,sid,score)函数,data列表每个元素的前5个数据项依次为学校编号、选手编号、成绩、校内名次、是否入选,列表已按成绩由高到低排列。函数功能是查找选手编号为sid、成绩为score的元素,返回其下标,若未找到则返回-1。
def search(data,sid,score):
left,right=0,len(data)-1
f=-1
while left<=right:
mid=(left+right)//2
if score==data[mid][2]:
f=mid
left=mid+1
elif score<data[mid][2]:
left=mid+1
else:
right=mid-1
if f==-1:
return-1
for i in range():
if data[i][2]!=score:
return-1
elif data[i][1]==sid:
return i
return-1
①调用search函数,若data列表长度为12,data[0][2],data[1][2],…,data[11][2]的值依次为:198,185,183,182,182,177,177,176,175,163,161,161,score值为177,则while语句中循环体的执行次数是 。
②程序中加框处代码有错,请改正。
(3)实现根据选手成绩(成绩不超过200)计算校内名次,以及挑选决赛选手功能的Python程序如下,请在划线处填入合适的代码。
def proc(data,n,s,w):
#创建r列表,共n个元素,每个元素的值均为[0,0,201],代码略
heads=[-1,-1]
tails=[-1,-1]
cnt=0
for i in range(len(data)):
r[k][1]+=1
if data[i][2]<r[k][2]:
r[k][2]=data[i][2]
data[i][3]=r[k][0]
data[i].append(-1) #为data[i]添加一个元素-1
v=1
if data[i][3]<=w:
data[i][4]=True
cnt+=1
v=0
if heads[v]==-1:
heads[v]=i
else:
data[tails[v]][5]=i
tails[v]=i
p,q=heads[0],heads[1]
res=[] #res列表用于存放入选决赛的选手编号,顺序与data列表保持一致
while cnt < s and q!=-1:
tmp=data[q][2]
while q!=-1 and data[q][2]==tmp:
:
res.append(data[p][1])
p=data[p][5]
res.append(data[q][1])
data[q][4]=True
cnt+=1
q=data[q][5]
while p!=-1:
res.append(data[p][1])
p=data[p][5]
return res
"读取n、s、w;读取选手成绩数据表存入data列表,每个元素包含学校编号、选手编号、成绩、校内名次(初值为0)、是否入选(初值为False)5个数据项,代码略"
res=proc(data,n,s,w)
#输出res列表中的入选选手编号,代码略
#读取待查询的选手编号与成绩,调用search函数,根据返回值输出查询结果,代码略
二、操作题
3.(2023·浙江·高考真题)某仓库有一排连续相邻的货位,编号依次为0-n-1,用于放置A、B两种类型的箱子,A型箱子占2个相邻货位,B型箱子占1个货位。编写程序,根据已完成的放置或搬离操作,输出空货位数及还可以放置A型箱子的最多数量(不移动已放置的箱子)。请回答下列问题:
箱子类型
操作类型
货位编号
B
放置
5
A
放置
2,3
B
放置
0
A
放置
7,8
A
搬离
2,3
(1)若n为10,开始时货位全空,经过如图所示的放置或搬离操作后,不移动已放置箱子的情况下,还可放置A型箱子的最多数量为 个。
(2)实现上述功能的部分Python程序如下,请在划线处填入合适的代码。
#读取货位总数,存入n,代码略。
cntl=n
1st=[0]*n #1货位状态,0表示对应的货位为空
while True:
#读取本次已操作的数据:箱子类型、操作类型、货位编号起始值,存入t、d和s,代码略
if t=='A':
w=2
① :
w=1
else: #t不是'A'或'B'时退出循环
break
if d=='P': #d为P时表示放置,否则表示搬离
②
else:
cnt l+=w
1st[s]=1-Ist[s]
if t=='A':
1st[s+1]=1-1st[s+1]
i,cnt2=0,0
while i<n-1:
if 1st[i]==0 and 1st[i+1]==0:
③
cnt2+=1
i+=1
print("当前空货位数:',cntl,',还可放置A型箱子的最多数量:',cnt2)
4.(2024·浙江·高考真题)某监控设备可定时采集红绿信号灯状态数据,数据格式记为[a,b],其中a、b分别为红灯和绿灯的状态值,0表示灯灭,1表示灯亮,如[0,1]表示红灯灭、绿灯亮。
现要编写程序,每隔1秒采集并检测信号灯是否存在如下异常状态:第一类,红绿灯同亮或同灭;第二类,红灯或绿灯超时,即保持同一状态时长大于上限值(如300秒)。检测到异常状态就发送相应信息。请回答下列问题:
(1)若检测到“红绿灯同亮”异常,则采集到的数据是 (单选,填字母)。
A.[0,0] B.[0,1] C.[1,0] D.[1,1]
(2)实现上述功能的部分Python程序如下,请在划线处填入合适的代码。
tlimit = 300 # 设置信号灯保持同一状态时长上限值
pre = [-1,-1]
t = [0,0] # t[0]、t[1]分别记录红灯、绿灯保持同一状态的时长
while True:
# 接收一次采集到的状态数据,存入d,代码略
if① :
if d[0] == 1:
# 发送“红绿灯同亮”信息,代码略
else:
# 发送“红绿灯同灭”信息,代码略
for i in② :
if d[i] == pre[i]:
t[i]+= 1
if③ :
if i == 0:
# 发送“红灯超时”信息,代码略
else:
# 发送“绿灯超时”信息,代码略
else:
t[i] = 1
pre = d
# 延时1秒,代码略
5.(2024·浙江·高考真题)某数据序列data中的元素均为小于127的正整数。现在要对data进行加密,处理过程分“变换”和“重排”两步。“变换”处理方法是用指定的n组序列 、…依次对data进行变换。利用Ri对data进行变换的过程是:在data中查找所有与Ri相同的子序列,将找到的每个子序列中的元素值加上Ri的长度值Li,并在各子序列前插入一个标记元素(值为127+Li),这些子序列及标记元素不再参与后续的变换。
如data为[3,5,1,6,3,8,7,5,1,8,7],指定的两组序列为[5,1]、[3,8,7],“变换”处理后的data为[3,129,7,3,6,130,6,11,10,129,7,3,8,7]。对data“重排”处理通过给定的shuff函数实现。
请回答下列问题:
(1)若data为[3,5,1,6,3,8,7,5,1,8,7],指定的两组序列为[5,1]、[8,7],经过“变换”处理后,data中插入的标记元素个数为 。
(2)“重排”处理的shuff函数如下:
def shuff(data, c): # 根据列表c对列表data进行重排
# 若列表data的长度不是列表c长度的整数倍,则用0补足,代码略
m = len(c)
s = [0] * m
k = 0
while k < len(data):
for i in range(m):
s[i] = data[k + i]
for i in range(m):
data[k + i] = s[c[i]]
k += m
若data为[3,129,7,3,130,6,11,10],c为[1,3,0,2],调用shuff(data, c)后,data的最后一个元素值为 。
(3)实现加密功能的部分Python程序如下,请在划线处填入合适的代码。
def compare(data, i, r):
# 函数功能:返回data从索引i位置、r从索引0位置开始的连续相等元素的个数
# 例如r为[7, 3, 6],data从索引i位置开始的元素依次为7, 6, 7, 3, …,函数返回1
j = 0
while j < len(r) and i + j < len(data):
if① :
break
else:
j += 1
return j
def trans(data, r, segs):
newsegs = []
for s in segs:
if s[0] == 0:
h = i = s[1]
m = len(r)
while i + m <= s[2] + 1:
if compare(data, i, r) == m:
if i > h:
newsegs.append([0, h, i-l]) # 为newsegs追加一个元素
newsegs.append([m, i, i + m-1])
i += m
②
else:
i += 1
if h <= s[2]:
newsegs.append([0, h, s[2]])
else:
newsegs.append(s)
return newsegs
def update(data, segs):
for s in segs:
if s[0] != 0:
data.append(0)
p = len(data)-1
for i in range(len(segs)-1, -1,-1):
for j in range(segs[i][2], segs[i][1]-1,-1):
③
p-= 1
if segs[i][0] > 0:
data[p] = 127 + segs[i][0]
p-= 1
# 读取待加密数据存入data,读取指定的若干组用于变换的序列存入rs,代码略
'''
列表segs用于记录data的变换信息,segs[i]包含三个元素,segs[i][0]、segs[i][1]、segs[i][2]分别表示data中一个子序列的状态、起始位置和结束位置,如果segs[i][0]为0,则表示该子序列未经过变换。
'''
segs = [[0,0,len(data)-1]]
for r in rs:
segs = trans(data,r,segs) # 根据r更新segs
update(data, segs) # 利用segs完成对data的变换操作
c = [1,3,0,2]
shuff(data, c)
# 输出加密后的data序列,代码略
6.(2023·浙江·高考真题)某工程包含n个任务(编号为0-n-1),每天可以有多个任务同时进行。某些任务之间有依赖关系,如图a所示,任务4依赖于任务1,任务1依赖于任务2。即任务2完成后才可以开始任务1,任务1完成后才可以开始任务4,不存在一个任务依赖于多个任务,或多个任务依赖于同一个任务的情况。
现已对该工程的依赖关系进行了梳理,结果如图b所示,标记“T”表示依赖关系需保留,标记“F”表示依赖关系需删除。
根据每个任务完成所需的天数和梳理后的依赖关系,编写程序,首先删除标记为“F”的依赖关系,然后计算工程最快完成所需的天数,并以工程最快完成所需的天数为期限,计算每个任务最晚必须开始的时间。
图a 图b
请回答下列问题:
(1)若某工程有6个任务,任务间依赖关系如图a所示,完成任务0~5所需天数分别为2,1,3,5,1,6,则工程最快完成需要 天。
(2)定义如下erase(1st)函数,参数1st列表的每个元素表示一个依赖关系。函数的功能是删除标记为“F”的依赖关系,返回保留的依赖关系的个数。
def erase(lst):
i=0
j=len(1st)-1
while i<=j:
if 1st[i][2]=='T':
i+=1
else:
if lst[j][2]=='T':
1st[i]=1st[j]
i+=1
j-=1
return i
若1st列表依次存储图b所示的依赖关系,如1st[0]为[0,5,T],调用erase(lst)的数,则语句
"1st[i]=1st[j]”的执行次数为 。
(3)实现上述功能的部分Python程序如下,请在划线处填入合适的代码。
def proc(n,lst,task):
pr=[0]*n
w=[0]*n #w[i]存放任务1最晚必须开始的时间
m=erase(1st)
for i in① :
task[lst[i][1]][1]=1st[i][0]
pr[lst[i][0]]=1
c=[]
days=0 #days存放工程最快完成所需的天数
for I in range(n):
if pr[i]==0:
k=i
s=0
while k!=-1:
c.append(k)
s+=task[k][0]
②
if s>days:
days=s
for i in range(n-1,-1,-1):
k=c[i]
if task[k][1]==-1:
w[k]=days-task[k][0]+1
else:
③
#输出days,以及保存在w中的每个任务最晚必须开始的时间,代码略
```
工程包含的任务数存入变量n
任务间的依赖关系存入1st列表
1st[0]包含3项,任务1st[i][0]依赖于任务1st[i][1],1st[i][2]存放保留/删除标记,任务数据存入task列表
task[i]包含2项,task[i][0]为完成任务主所需天数,task[i][1]的初值为-1
代码略
```
proc(n,1st,task)
7.(2023·浙江·高考真题)有2组器件共n个,要用一台检测设备检测。每个送检器件的信息包含送达时间、检测时长和优先级。优先级有m(l<m<6)个等级。由高到低分别用0-m-l的整数表示。每个机器件的送达时间各不相同,已送达的器件按照各优先级通道分别排队,先到达先入队,设备每次检测都从当前各非空队列中,选取优先级最高的队列的队首器件出队进行检测。(同一时刻出现入队和出队时,先处理入队。)
编写程序模拟检测过程,先合并2组器件的数据,然后计算所有器件的平均等待时长,其中每个器件等待时长为其开始检测的时间与送达时间的时间差。(时间单位均为秒)
请回答下列问题:
(l)由题意可知,图中器件A、B、C、D的检测顺序为A-C-D-B,A、C、D的等待时长分别为0、l、0,B的等待时长是 。
(2)定义如下merge(1stl,lst2)函数,参数lstl和lst2的每个元素由送达时间、检测时长和优先级3项构成,1stl和lst2均已按送达时间升序排列。函数功能是将lst2中的元素合并到1stl中,并将1stl按送达时间升序排列,函数返回1stl。
def merge(1stl,Ist2)
i=len(lstl)-l
j=len(lst2)-1
for t in range(len(lst2)):
1stl.append([0,0,0]) #为1stl追加一个元素[0,0,0]
k=len(1stl)-1
while j>=0:
if i>=0 and 1stl[i][0]>lst2[j][0]:
1stl[k]=1stl[i]
i-=l
else:
1stl[k]=lst2[j]
j-=l
k-=1
return 1stl
①调用merge(1stl,lst2)函数,若1stl为([0,3,2],[1,1,2],[12,2,2]],1st2为[2,l,1],[4,3,0],[1l,3,2]],则while语句中循环体的执行次数是 。
②若函数中while语句的条件“j>=0”误写为“k>=0”,会导致某些情况下无法得到符合函数功能的结果。调用merge(1stl,lst2)函数,下列4组数据中能测试出这一问题的是 (单选,填字母)。
A.1stl=[[0,3,2],[4,3,0]]
lst2=[[1,1,2J]
B.1stl=[[1,1,2]]
1st2=[[0,3,2],[4,3,0]]
C.1stl=[[l,1,2],[4,3,0]]
lst2=[[0,3,2]]
D.1stl=[[4,3,0]]
1st2=[[0,3,2],[l,1,2]]
(3)实现模拟检测过程并计算平均等待时长的部分Python程序如下,请在划线处填入合适的代码。
def proc(data,m):
n=len(data)
queinfo=[]
for i in range(m):
queinfo append([-l,-1]) #queinfo追加一个元素[-l,-1]
for i in range(n):
data[i].append(-1) #data]追加一个元素-1
curtime=0
waitnum=0
i=0
①
while i<n or waitnum>0:
if i<n and datalill0]<=curtime:
k=data[i][2]
if queinfo[k][0]==-l:
queinfo[k][0]=i
else:
②
data[p][3]=i
queinfo[k][1]=i
waitnum+=l
i+=l
elif waitnum>0:
k=0
while queinfo[k][0]= =-1:
k+=l
p=queinfo[k][0]
total +=curtime-data[p][0]
curtime+=data[p][1]
③
waitnum-=1
else:
curtime=data[i][0]
return total/n
读取2组器件的数据,分别存入列表data1和data2中。2个列表的每个元素包含3个数据项,分别对应器件的送达时间、检测时长和优先级。data1和data2中的数据已分别按送达时间升序排列,代码略
读取优先级等级个数存入m,代码略
…
data=merge(data1,data2)
print(proc(data,m))
8.(2024·浙江·高考真题)某项活动有n个单位(编号1到n)参加,需将员工分成若干个小组,每个小组的人数上限为m,小组编号按新建次序从1开始编号。分组时,首先按单位编号次序依次在各单位内部分组,每m人分配到一个新建小组中,不足m人的剩余员工暂不分配;然后按剩余员工人数由大到小的顺序,依次为各单位剩余员工分配小组。
若某单位剩余员工人数为k,则分配方法为:在已建的小组中查找空位数(该小组还可容纳的人数)大于或等于k的小组,如果找到的小组有多个,则选择空位数最少的小组,将此k人分配到该小组中;如果没有找到,则新建一个小组,将此k人分配到该小组中。
设n为5,m为20,各单位员工人数及单位内部的分组过程如图a所示,各单位剩余员工的分组过程如图b所示。
图a 图b
编写程序:给定各单位编号及员工人数,根据上述方法进行分组处理,按单位编号次序输出各单位所分配的分组编号。请回答下列问题:
(1)由题意可知,若仅将图a中1号单位的员工人数修改为25,然后对图中5个单位重新分组,则1号单位所分配的分组编号为 。
(2)定义如下bubble_sort(lst)函数,参数lst的每个元素由单位编号和剩余员工人数2个数据项构成。函数的功能是根据每个单位的剩余员工人数,对lst进行降序排序。
def bubble_sort(lst):
n = len(lst)
for i in range(0,n-1):
for j in range(n-1,i,-1):
if lst[j-1][1] < lst[j][1]:
tmp = lst[j]
lst[j] = lst[j-1]
lst[j-1] = tmp
if lst[i][1] == 0:
break
return
调用该函数,若lst为[[1,0],[2,0],[3,18],[4,0],[5,19],[6,17]],请回答①和②两个问题。
①虚线框中的程序段第1次执行后,关于lst中的剩余员工人数,下列说法正确的是 (单选,填字母)
A.lst[0][1]数值最小 B.lst[0][1]数值最大 C.lst[5][1]数值最小 D.lst[5][1]数值最大
②虚线框中的程序段执行的次数为 。
(3)实现分组功能的部分Python程序如下,程序中用到的列表函数与方法如图c所示,请在程序中划线处填入合适的代码。
图c
def group(data,m):
n = len(data)
a = []
for i in range(n+1):
a.append([])#a[i]初始为空列表,存放编号为i的单位所分配的分组编号
gnum=0
for i in range(n):#各单位内部分组
while data[i][1] >= m:
gnum += 1
k = data[i][0]
a[k].append(gnum)
①
bubble_sort(data)#根据每个单位的剩余员工人数,对data进行降序排序
b = []
for i in range(m):
b.append([])
i = 0
while i < n and data[i][1] != 0:#对剩余员工分组
②
while j < m and len(b[j])== 0:
j += 1
if j < m:
v = b[j].pop()
else:
gnum += 1
v = gnum
a[data[i][0]].append(v)
③
i += 1
#输出各单位的分组编号,代码略
'''
读取小组人数上限存入m;读取1至n号单位的数据,依次存入列表 data 的 data[0]至data[n-1]中。data[i]包含2个数据项,data[i][0],data[i][1]分别存放单位编号及员工人数,代码略
'''
group(data,m)
试卷第1页,共3页
试卷第1页,共3页
学科网(北京)股份有限公司
参考答案
1.(1)2 (2)a[i]>90 t=i cnt==0
2. 3 4 f,-1,-1 k=data[i][0] r[k][0]=r[k][1] while p!=-1 and p<q
3. 2或“两” elif t=='B' 或elif t=="B" 或elif t==""B"" 或elif(t= ='B') cntl-=w 或cntl=cntl-w i+=1 或i=i+1
4. D d[0] == d[1] range(2) 或range(len(pre)) 或range(len(d)) t[i]>tlimit
5. 4 11 r[j]!=data[i+j] h=i data[p]=data[j]+segs[i][0]
6. 8 1 range(m) 或range(0,m) 或range(0,m,1) 或range(m-1,-1,-1)或range(erase(1st)) 或range(0,erase(1st)) 或range(0,erase(1st),1) 或range(erase(1st)-1,-1,-1) k=task[k][1] w[k]=w[task[k][1]]-task[k][0] 或w[k]=w[c[i+1]]-task[k][0] 这里面可以把k换成c[i]
7. 6 4 A total=0 p= queinfo[k][1] queinfo[k][0]=data[p][3]
8. 1,8 B 4 data[i][1]-=m j=data[i][1] b[j-data[i][1]].append(v)
答案第1页,共2页
答案第1页,共2页
学科网(北京)股份有限公司
$$
Python程序综合应用填空题
一、综合应用题
1.(2025·浙江·高考真题)根据机器的负载率对工厂的6台机器(编号0~5)进行监控和调度,调度规则是:每隔1小时采集1次各台机器的负载率(负载率用百分制表示,例如,负载率95%表示为95,机器休息时的负载率为0),负载率超过90的机器都调度休息;如果所有机器负载率都不超过90,则负载率最高的机器休息,若多台机器负载率同为最高,则编号最小的机器休息,休息的机器在休息1小时后再次工作。
请回答下列问题:
(1)若某次采集到0~5号机器的负载率依次为75、85、88、0、88、87,当前处于休息状态的机器编号3,接下来休息的机器编号是 。
(2)实现上述功能的部分Python程序如下,请在划线处填入合适的代码。
n=6 #机器台数
a=[0]*n #列表a长度为n,各元素值均为0
#启动0~4号机器工作,5号机器休息,代码略
while True:
#延时1小时,再采集各机器负载率存入a,a[i]存放i号机器的负载率,代码略
t=0
cnt=0
for i in range(n):
if :
#调度i号机器休息,代码略
cnt+=1
if a[i]>a[t]:
elif a[i]==0:
#调度i号机器工作,代码略
if :
#调度t号机器休息,代码略
【答案】(1)2 (2)a[i]>90 t=i cnt==0
【知识点】分支结构的程序实现
【详解】本题考查分支结构的程序实现。
(1)某次采集到的机器负载率中,超过 90 的机器没有。在不超过 90 的负载率中,最高负载率为 88,有编号为 2 和 4 的机器负载率都是 88,按照 “若多台机器负载率同为最高,则编号最小的机器休息” 的规则,接下来休息的机器编号是 2。
(2)①处: 该处需要判断哪些机器的负载率超过 90,从而调度其休息。根据调度规则,负载率超过 90 的机器都调度休息,所以此处应判断a[i] > 90。因此该空答案为a[i] > 90。
②处: 这里是在寻找负载率最高的机器编号。当a[i] > a[t]时,说明当前机器i的负载率比之前记录的最高负载率机器t的负载率还要高,所以要更新t为当前机器编号i。因此该空答案为t = i。
③处: 此处是判断当所有机器负载率都不超过 90 时,调度负载率最高的机器休息(若多台机器负载率同为最高,则编号最小的机器休息)。cnt用于统计负载率超过 90 的机器数量,当cnt为 0 时,表示所有机器负载率都不超过 90,此时就需要调度负载率最高的机器休息。因此该空答案为cnt == 0。
2.(2025·浙江·高考真题)某市举行体育赛事活动,n所学校的选手已完成预赛,现计划根据预赛的成绩挑选s名选手参加市决赛。成绩位列所在学校前w名次的选手直接入选,剩余名额按成绩由高到低依次挑选,成绩相同的选手一并入选,选中的选手数一旦达到或超过s名,挑选结束。
现给定所有选手预赛的成绩数据表,每位选手的数据包含学校编号(0~n-1)、选手编号、成绩,成绩数据表已按成绩由高到低排列。编写程序,计算各选手的校内名次,再按上述规则挑选决赛选手,按成绩数据表中的顺序输出选手编号,同时提供查询功能。选手校内名次的计算方法是:若选手所在学校有m人成绩高于该选手,则该选手的名次为m+1。
在图所示的样例中,n、s、w分别为3、8、2,根据图中前3行数据计算出了每位选手的校内名次,进而选出实际入选的9名选手。
学校编号
0
2
2
0
0
2
2
0
1
1
1
1
选手编号
0002
2027
2002
0072
0182
2071
2128
0012
1081
1002
1008
1208
成绩
198
185
183
182
182
177
177
176
175
163
161
161
校内名次
1
1
2
2
2
3
3
4
1
2
3
3
是否入选
True
True
True
True
True
True
True
False
True
True
False
False
请回答下列问题:
(1)对于图所示前4行数据,若s、w分别为5和1,则0号学校入选人数是 。
(2)定义如下search(data,sid,score)函数,data列表每个元素的前5个数据项依次为学校编号、选手编号、成绩、校内名次、是否入选,列表已按成绩由高到低排列。函数功能是查找选手编号为sid、成绩为score的元素,返回其下标,若未找到则返回-1。
def search(data,sid,score):
left,right=0,len(data)-1
f=-1
while left<=right:
mid=(left+right)//2
if score==data[mid][2]:
f=mid
left=mid+1
elif score<data[mid][2]:
left=mid+1
else:
right=mid-1
if f==-1:
return-1
for i in range():
if data[i][2]!=score:
return-1
elif data[i][1]==sid:
return i
return-1
①调用search函数,若data列表长度为12,data[0][2],data[1][2],…,data[11][2]的值依次为:198,185,183,182,182,177,177,176,175,163,161,161,score值为177,则while语句中循环体的执行次数是 。
②程序中加框处代码有错,请改正。
(3)实现根据选手成绩(成绩不超过200)计算校内名次,以及挑选决赛选手功能的Python程序如下,请在划线处填入合适的代码。
def proc(data,n,s,w):
#创建r列表,共n个元素,每个元素的值均为[0,0,201],代码略
heads=[-1,-1]
tails=[-1,-1]
cnt=0
for i in range(len(data)):
r[k][1]+=1
if data[i][2]<r[k][2]:
r[k][2]=data[i][2]
data[i][3]=r[k][0]
data[i].append(-1) #为data[i]添加一个元素-1
v=1
if data[i][3]<=w:
data[i][4]=True
cnt+=1
v=0
if heads[v]==-1:
heads[v]=i
else:
data[tails[v]][5]=i
tails[v]=i
p,q=heads[0],heads[1]
res=[] #res列表用于存放入选决赛的选手编号,顺序与data列表保持一致
while cnt < s and q!=-1:
tmp=data[q][2]
while q!=-1 and data[q][2]==tmp:
:
res.append(data[p][1])
p=data[p][5]
res.append(data[q][1])
data[q][4]=True
cnt+=1
q=data[q][5]
while p!=-1:
res.append(data[p][1])
p=data[p][5]
return res
"读取n、s、w;读取选手成绩数据表存入data列表,每个元素包含学校编号、选手编号、成绩、校内名次(初值为0)、是否入选(初值为False)5个数据项,代码略"
res=proc(data,n,s,w)
#输出res列表中的入选选手编号,代码略
#读取待查询的选手编号与成绩,调用search函数,根据返回值输出查询结果,代码略
【答案】 3 4 f,-1,-1 k=data[i][0] r[k][0]=r[k][1] while p!=-1 and p<q
【知识点】查找算法的应用、队列的基本操作
【详解】本题考查二分查找,队列。
(1)对于题中图所示前 4 行数据,若 s、w 分别为 5 和 1,则 0 号学校入选人数是:①成绩位列所在学校前1名次的选手直接入选。0 号学校前 4 行数据中,成绩为 198 的选手排名第 1,直接入选;②剩余名额按成绩由高到低依次挑选,成绩相同的选手一并入选,选中的选手数一旦达到或超过5名,挑选结束。0号学校成绩为 182 的选手有 2 人(182排名第5),这两人一并入选。因此入选人数是3 。
(2)本题是二分查找变形,当找到相同成绩的时候,并不跳出循环,而是移动左指针到 mid 的右侧,变量f记录了成绩为 score 的元素最后一次出现的位置,①调用search函数,在while left <= right循环中,第一次循环:mid = (0 + 11) // 2 = 5,data[5][2] == 177,找到第一个值为 177 的元素,f = 5,left = 6;第二次循环:mid = (6 + 11) // 2 = 8,data[8][2] < 177,right= 7;第三次循环:mid = (6 + 7) // 2 = 6,data[6][2] = 177,left =7;第四次循环:mid = (7 + 7) // 2 = 7,data[7][2] < 177,right = 6,此时left > right,循环结束。所以while语句中循环体的执行次数是 4 次。
②f记录了成绩为 score 的元素最后一次出现的位置,在此基础上寻找编号为 sid 的选手需要从后往前遍历,所以range(f,len(data))应改成range(f,-1,-1),因此答案是f,-1,-1。
(3)①处:这里是要根据学校编号找到对应的统计数组r的索引k,所以应填入k = data[i][0]。 ②处:如果当前选手的成绩小于前面记录的成绩,那么更新最新处理成绩值,并且更新最新处理成绩值对应的名次值,即r[k][0]=r[k][1]。 ③处:指针p、指针q初始化为直接入选队列、剩余按成绩入选队列的队首位置,res列表用于存放入选决赛的选手编号。当选中的选手数量未达到s人且剩余按成绩入选队列未被遍历完时进行处理。每趟循环取出剩余按成绩入选队列中成绩最高的元素,先将直接入选队列中成绩高于该元素成绩值tmp 的元素添加到res中,再将剩余队列中成绩相同的选手一并入选。所以,该处需要保证直接入选队列先于剩余按成绩入选队列入选。因此该空答案是while p!=-1 and p<q。
二、操作题
3.(2023·浙江·高考真题)某仓库有一排连续相邻的货位,编号依次为0-n-1,用于放置A、B两种类型的箱子,A型箱子占2个相邻货位,B型箱子占1个货位。编写程序,根据已完成的放置或搬离操作,输出空货位数及还可以放置A型箱子的最多数量(不移动已放置的箱子)。请回答下列问题:
箱子类型
操作类型
货位编号
B
放置
5
A
放置
2,3
B
放置
0
A
放置
7,8
A
搬离
2,3
(1)若n为10,开始时货位全空,经过如图所示的放置或搬离操作后,不移动已放置箱子的情况下,还可放置A型箱子的最多数量为 个。
(2)实现上述功能的部分Python程序如下,请在划线处填入合适的代码。
#读取货位总数,存入n,代码略。
cntl=n
1st=[0]*n #1货位状态,0表示对应的货位为空
while True:
#读取本次已操作的数据:箱子类型、操作类型、货位编号起始值,存入t、d和s,代码略
if t=='A':
w=2
① :
w=1
else: #t不是'A'或'B'时退出循环
break
if d=='P': #d为P时表示放置,否则表示搬离
②
else:
cnt l+=w
1st[s]=1-Ist[s]
if t=='A':
1st[s+1]=1-1st[s+1]
i,cnt2=0,0
while i<n-1:
if 1st[i]==0 and 1st[i+1]==0:
③
cnt2+=1
i+=1
print("当前空货位数:',cntl,',还可放置A型箱子的最多数量:',cnt2)
【答案】 2或“两” elif t=='B' 或elif t=="B" 或elif t==""B"" 或elif(t= ='B') cntl-=w 或cntl=cntl-w i+=1 或i=i+1
【知识点】典型算法
【详解】本题考查Python基础应用能力。(1)若n为10,开始时货位全空,经过如图所示的放置或搬离操作后,空的货位编号有:1、2、3、4、6、9,因为A型箱子占2个相邻货位,故不移动已放置箱子的情况下,还可放置A型箱子的最多数量为2(放置在货位编号1、2和3、4)。(2)阅读程序可知,cnt1是空货位数量,w变量为应搬离的数量,由下一条语句w=1可知,第一空应为:elif t=='B'或其他等价答案;d=='P'表示放置,搬离时空位加w,则放置时空位减w,故第二空应为:cntl-=w或其他等价答案; 在统计连续两个空位的个数时,统计完后指针i要向后跳2,由于if外指针i已经后跳1,故第三空应为:i+=1。
4.(2024·浙江·高考真题)某监控设备可定时采集红绿信号灯状态数据,数据格式记为[a,b],其中a、b分别为红灯和绿灯的状态值,0表示灯灭,1表示灯亮,如[0,1]表示红灯灭、绿灯亮。
现要编写程序,每隔1秒采集并检测信号灯是否存在如下异常状态:第一类,红绿灯同亮或同灭;第二类,红灯或绿灯超时,即保持同一状态时长大于上限值(如300秒)。检测到异常状态就发送相应信息。请回答下列问题:
(1)若检测到“红绿灯同亮”异常,则采集到的数据是 (单选,填字母)。
A.[0,0] B.[0,1] C.[1,0] D.[1,1]
(2)实现上述功能的部分Python程序如下,请在划线处填入合适的代码。
tlimit = 300 # 设置信号灯保持同一状态时长上限值
pre = [-1,-1]
t = [0,0] # t[0]、t[1]分别记录红灯、绿灯保持同一状态的时长
while True:
# 接收一次采集到的状态数据,存入d,代码略
if① :
if d[0] == 1:
# 发送“红绿灯同亮”信息,代码略
else:
# 发送“红绿灯同灭”信息,代码略
for i in② :
if d[i] == pre[i]:
t[i]+= 1
if③ :
if i == 0:
# 发送“红灯超时”信息,代码略
else:
# 发送“绿灯超时”信息,代码略
else:
t[i] = 1
pre = d
# 延时1秒,代码略
【答案】 D d[0] == d[1] range(2) 或range(len(pre)) 或range(len(d)) t[i]>tlimit
【知识点】循环结构的程序实现
【详解】本题考查的是Python综合应用。
(1)依据题干数据说明可知,1表示灯亮,若检测到“红绿灯同亮”异常,则采集到的数据是: [1,1]。选D。
(2)①处,由嵌套的分支可知,该分支处理的是:红绿灯同亮或同灭(即红绿灯状态相同),故此处应为:d[0] == d[1] ;②处,从for循环中语句的调用来看,i是数组d和pre的下标索引,i取0到1,故此处应为:range(2)或 range(len(d))或range(len(pre));③处,若d[i]==pre[i],表示i所对应的红绿灯相邻两个时刻的状态相同,则相应的红绿灯时长t[i]计数;若时长超过上限值,则表示异常状态;若此时i==0表示红灯异常;否则表示绿灯异常,故此处应为:t[i]>tlimit。
5.(2024·浙江·高考真题)某数据序列data中的元素均为小于127的正整数。现在要对data进行加密,处理过程分“变换”和“重排”两步。“变换”处理方法是用指定的n组序列 、…依次对data进行变换。利用Ri对data进行变换的过程是:在data中查找所有与Ri相同的子序列,将找到的每个子序列中的元素值加上Ri的长度值Li,并在各子序列前插入一个标记元素(值为127+Li),这些子序列及标记元素不再参与后续的变换。
如data为[3,5,1,6,3,8,7,5,1,8,7],指定的两组序列为[5,1]、[3,8,7],“变换”处理后的data为[3,129,7,3,6,130,6,11,10,129,7,3,8,7]。对data“重排”处理通过给定的shuff函数实现。
请回答下列问题:
(1)若data为[3,5,1,6,3,8,7,5,1,8,7],指定的两组序列为[5,1]、[8,7],经过“变换”处理后,data中插入的标记元素个数为 。
(2)“重排”处理的shuff函数如下:
def shuff(data, c): # 根据列表c对列表data进行重排
# 若列表data的长度不是列表c长度的整数倍,则用0补足,代码略
m = len(c)
s = [0] * m
k = 0
while k < len(data):
for i in range(m):
s[i] = data[k + i]
for i in range(m):
data[k + i] = s[c[i]]
k += m
若data为[3,129,7,3,130,6,11,10],c为[1,3,0,2],调用shuff(data, c)后,data的最后一个元素值为 。
(3)实现加密功能的部分Python程序如下,请在划线处填入合适的代码。
def compare(data, i, r):
# 函数功能:返回data从索引i位置、r从索引0位置开始的连续相等元素的个数
# 例如r为[7, 3, 6],data从索引i位置开始的元素依次为7, 6, 7, 3, …,函数返回1
j = 0
while j < len(r) and i + j < len(data):
if① :
break
else:
j += 1
return j
def trans(data, r, segs):
newsegs = []
for s in segs:
if s[0] == 0:
h = i = s[1]
m = len(r)
while i + m <= s[2] + 1:
if compare(data, i, r) == m:
if i > h:
newsegs.append([0, h, i-l]) # 为newsegs追加一个元素
newsegs.append([m, i, i + m-1])
i += m
②
else:
i += 1
if h <= s[2]:
newsegs.append([0, h, s[2]])
else:
newsegs.append(s)
return newsegs
def update(data, segs):
for s in segs:
if s[0] != 0:
data.append(0)
p = len(data)-1
for i in range(len(segs)-1, -1,-1):
for j in range(segs[i][2], segs[i][1]-1,-1):
③
p-= 1
if segs[i][0] > 0:
data[p] = 127 + segs[i][0]
p-= 1
# 读取待加密数据存入data,读取指定的若干组用于变换的序列存入rs,代码略
'''
列表segs用于记录data的变换信息,segs[i]包含三个元素,segs[i][0]、segs[i][1]、segs[i][2]分别表示data中一个子序列的状态、起始位置和结束位置,如果segs[i][0]为0,则表示该子序列未经过变换。
'''
segs = [[0,0,len(data)-1]]
for r in rs:
segs = trans(data,r,segs) # 根据r更新segs
update(data, segs) # 利用segs完成对data的变换操作
c = [1,3,0,2]
shuff(data, c)
# 输出加密后的data序列,代码略
【答案】 4 11 r[j]!=data[i+j] h=i data[p]=data[j]+segs[i][0]
【知识点】Python语言基础
【详解】本题考查Python程序设计相关内容。本题涉及到索引数组和双指针知识。结合题目内容,分析程序段,推知:
(1)考查基本的数据模拟能力,变换数组r = [[5, 1], [8, 7]],在序列data中,分别以索引号1、5、7、9为起始的包含两个元素的子序列与r序列中的子序列相等,则有4个子串进行变换。题目要求在各子序列前插入一个标记元素,则共插入4个标记元素,故本题答案为:4。
(2)考查索引数组。由题目描述知,索引数组的长度可能小于原数组,当原数组索引超过索引数组的索引范围时,需要对原数组进行分组,应以索引数组的长度m作为每一组的元素个数,若不足,则用0补齐。data长度为c的整数倍,则调用shuff函数后,data的最后一个元素是分组后最后一组重排结果的最后一项, c[3] = 2,最后一组的元素值为[130, 6, 11, 10],所以索引2处的值为11。故本题答案为:11。
(3)考察用变换实现加密功能。compare函数返回data从索引i位置、r从索引0位置开始的连续相等元素的个数,trans函数处理序列变换,update函数用于完成子串的变换和标记元素的插入。③处,compare函数中,j是r的索引,i是data的索引,该函数用于检查data中是否存在从索引i开始的连续j项均与r相同,返回相同项的数量。若data[i + j] != r[j]成立,表明查询结束,应结束循环,故③处答案为:r[j]!=data[i+j]。④处,trans函数的3个参数:data表示原始数据,r是当前变换数组,segs记录了当前data的变换信息。对于其中一条变换信息s,s[0] == 0表明该信息所描述的子串没有经过标记,可以进行变换。若compare(data, i, r) == m成立,表明找到了需要进行变换的子串data[i: i + m],此时,若i > h成立,则需要新增data[h: i]的未标记子序列和data[i: i + m]的标记子序列(标记值恰为m),与此同时,该子序列中data[h: i + m]均为已处理状态,在i += m后更新h = i的作用是更新该子序列的头部标记,故④处答案为:h=i。⑤处,update函数根据变换信息处理data数据中的具体更新,函数中需要实现元素插入的功能,因此需要逆序遍历data,trans函数采用队列保证变换信息的有序性,逆序遍历变换信息的同时可以逆序遍历data,以免因数据的插入而影响原始数据。索引p用于逆向遍历插入后data,索引j从变换信息的“结束索引”逆向遍历到“开始索引”,由于变换信息中存储的是data的原始数据信息,因此data[p] = data[j] + segs[i][0]即为对data[j]的变换值的更新并移动到最终的位置上,故⑤处答案为:data[p]=data[j]+segs[i][0]。
6.(2023·浙江·高考真题)某工程包含n个任务(编号为0-n-1),每天可以有多个任务同时进行。某些任务之间有依赖关系,如图a所示,任务4依赖于任务1,任务1依赖于任务2。即任务2完成后才可以开始任务1,任务1完成后才可以开始任务4,不存在一个任务依赖于多个任务,或多个任务依赖于同一个任务的情况。
现已对该工程的依赖关系进行了梳理,结果如图b所示,标记“T”表示依赖关系需保留,标记“F”表示依赖关系需删除。
根据每个任务完成所需的天数和梳理后的依赖关系,编写程序,首先删除标记为“F”的依赖关系,然后计算工程最快完成所需的天数,并以工程最快完成所需的天数为期限,计算每个任务最晚必须开始的时间。
图a 图b
请回答下列问题:
(1)若某工程有6个任务,任务间依赖关系如图a所示,完成任务0~5所需天数分别为2,1,3,5,1,6,则工程最快完成需要 天。
(2)定义如下erase(1st)函数,参数1st列表的每个元素表示一个依赖关系。函数的功能是删除标记为“F”的依赖关系,返回保留的依赖关系的个数。
def erase(lst):
i=0
j=len(1st)-1
while i<=j:
if 1st[i][2]=='T':
i+=1
else:
if lst[j][2]=='T':
1st[i]=1st[j]
i+=1
j-=1
return i
若1st列表依次存储图b所示的依赖关系,如1st[0]为[0,5,T],调用erase(lst)的数,则语句
"1st[i]=1st[j]”的执行次数为 。
(3)实现上述功能的部分Python程序如下,请在划线处填入合适的代码。
def proc(n,lst,task):
pr=[0]*n
w=[0]*n #w[i]存放任务1最晚必须开始的时间
m=erase(1st)
for i in① :
task[lst[i][1]][1]=1st[i][0]
pr[lst[i][0]]=1
c=[]
days=0 #days存放工程最快完成所需的天数
for I in range(n):
if pr[i]==0:
k=i
s=0
while k!=-1:
c.append(k)
s+=task[k][0]
②
if s>days:
days=s
for i in range(n-1,-1,-1):
k=c[i]
if task[k][1]==-1:
w[k]=days-task[k][0]+1
else:
③
#输出days,以及保存在w中的每个任务最晚必须开始的时间,代码略
```
工程包含的任务数存入变量n
任务间的依赖关系存入1st列表
1st[0]包含3项,任务1st[i][0]依赖于任务1st[i][1],1st[i][2]存放保留/删除标记,任务数据存入task列表
task[i]包含2项,task[i][0]为完成任务主所需天数,task[i][1]的初值为-1
代码略
```
proc(n,1st,task)
【答案】 8 1 range(m) 或range(0,m) 或range(0,m,1) 或range(m-1,-1,-1)或range(erase(1st)) 或range(0,erase(1st)) 或range(0,erase(1st),1) 或range(erase(1st)-1,-1,-1) k=task[k][1] w[k]=w[task[k][1]]-task[k][0] 或w[k]=w[c[i+1]]-task[k][0] 这里面可以把k换成c[i]
【知识点】链表的特性
【详解】本题考查数组、链表相关操作。(1)依据题干,将所有任务分为三组:[5,0]需要8天、[4,1,2]需要5天、[3]需要5天,三组任务可以同时进行,取最多的天数即为工程最快完成时间。故工程最快完成需要8天。(2)erase(1st)函数用于删除1st列表中标记为删除的任务。该函数遍历lst列表,通过两个指针i和j,分别指向列表的头部和尾部。当1st[i][2]为T时,表示该任务需要保留,指针i向后移动一位。当1st[i][2]不为'T'时,表示该任务需要删除,将1st[i]替换为1st[j],然后指针i向后移动一位,指针j向前移动一位。最后返回指针i的值,即删除后的列表长度,不管尾元素是否标记为“F”,j都向前移动一个位置。结合图b,可知语句“1st[i]=1st[j]”只在i=1,j=3时执行1次。(3)自定义函数proc(n,1st,task),用于处理任务调度。lst中已经删除了标记为“F”的依赖关系,erase(1st)函数返回值为i赋值给了m,正好代表了剩余的元素个数,所以一空应填写range(m)或等价表达式。对于每个删除后的任务1st[i],将1st[i][0]作为任务的编号,将1st[i][1]作为任务的前置任务编号,将1st[i][0]作为任务的主任务编号。并将pr[lst[i][0]]设置为1,表示该任务有前置任务。空列表c,用于存放可以进行的任务序列。变量days用于存放工程最快完成所需的天数。接下来,遍历任务列表,对于每个任务编号i,如果该任务的前置任务编号为0,则将其作为起始任务,进行任务序列完成时间的计算。在计算过程中,将当前任务编号k添加到列表c中,累加任务的完成时间s,并将当前任务的主任务编号task[k][1]作为下一个任务的前置任务编号k,所以第二空的答案为k=task[k][1]。最后,如果累加完成时间s大于days,则更新days的值。接下来,通过倒序遍历任务列表,计算每个任务的最晚开始时间。对于每个任务编号k,如果该任务没有后续任务(即task[k][1]为-1),则将最晚开始时间w[k]设置为days-task[k][0]+1,表示该任务必须在工程最快完成时间内开始。否则,将最晚开始时间w[k]设置为其后续任务的最晚开始时间减去当前任务完成时间,表示该任务必须在其后续任务完成前开始。所以第三空的答案为w[k]=w[task[k][1]]-task[k][0]。
7.(2023·浙江·高考真题)有2组器件共n个,要用一台检测设备检测。每个送检器件的信息包含送达时间、检测时长和优先级。优先级有m(l<m<6)个等级。由高到低分别用0-m-l的整数表示。每个机器件的送达时间各不相同,已送达的器件按照各优先级通道分别排队,先到达先入队,设备每次检测都从当前各非空队列中,选取优先级最高的队列的队首器件出队进行检测。(同一时刻出现入队和出队时,先处理入队。)
编写程序模拟检测过程,先合并2组器件的数据,然后计算所有器件的平均等待时长,其中每个器件等待时长为其开始检测的时间与送达时间的时间差。(时间单位均为秒)
请回答下列问题:
(l)由题意可知,图中器件A、B、C、D的检测顺序为A-C-D-B,A、C、D的等待时长分别为0、l、0,B的等待时长是 。
(2)定义如下merge(1stl,lst2)函数,参数lstl和lst2的每个元素由送达时间、检测时长和优先级3项构成,1stl和lst2均已按送达时间升序排列。函数功能是将lst2中的元素合并到1stl中,并将1stl按送达时间升序排列,函数返回1stl。
def merge(1stl,Ist2)
i=len(lstl)-l
j=len(lst2)-1
for t in range(len(lst2)):
1stl.append([0,0,0]) #为1stl追加一个元素[0,0,0]
k=len(1stl)-1
while j>=0:
if i>=0 and 1stl[i][0]>lst2[j][0]:
1stl[k]=1stl[i]
i-=l
else:
1stl[k]=lst2[j]
j-=l
k-=1
return 1stl
①调用merge(1stl,lst2)函数,若1stl为([0,3,2],[1,1,2],[12,2,2]],1st2为[2,l,1],[4,3,0],[1l,3,2]],则while语句中循环体的执行次数是 。
②若函数中while语句的条件“j>=0”误写为“k>=0”,会导致某些情况下无法得到符合函数功能的结果。调用merge(1stl,lst2)函数,下列4组数据中能测试出这一问题的是 (单选,填字母)。
A.1stl=[[0,3,2],[4,3,0]]
lst2=[[1,1,2J]
B.1stl=[[1,1,2]]
1st2=[[0,3,2],[4,3,0]]
C.1stl=[[l,1,2],[4,3,0]]
lst2=[[0,3,2]]
D.1stl=[[4,3,0]]
1st2=[[0,3,2],[l,1,2]]
(3)实现模拟检测过程并计算平均等待时长的部分Python程序如下,请在划线处填入合适的代码。
def proc(data,m):
n=len(data)
queinfo=[]
for i in range(m):
queinfo append([-l,-1]) #queinfo追加一个元素[-l,-1]
for i in range(n):
data[i].append(-1) #data]追加一个元素-1
curtime=0
waitnum=0
i=0
①
while i<n or waitnum>0:
if i<n and datalill0]<=curtime:
k=data[i][2]
if queinfo[k][0]==-l:
queinfo[k][0]=i
else:
②
data[p][3]=i
queinfo[k][1]=i
waitnum+=l
i+=l
elif waitnum>0:
k=0
while queinfo[k][0]= =-1:
k+=l
p=queinfo[k][0]
total +=curtime-data[p][0]
curtime+=data[p][1]
③
waitnum-=1
else:
curtime=data[i][0]
return total/n
读取2组器件的数据,分别存入列表data1和data2中。2个列表的每个元素包含3个数据项,分别对应器件的送达时间、检测时长和优先级。data1和data2中的数据已分别按送达时间升序排列,代码略
读取优先级等级个数存入m,代码略
…
data=merge(data1,data2)
print(proc(data,m))
【答案】 6 4 A total=0 p= queinfo[k][1] queinfo[k][0]=data[p][3]
【知识点】典型算法
【详解】本题考查的是Python综合应用。(1)D检测完后时间为:3+4=7,B送达时间为1,故等待时间为:7-1=6。(2)①初始j= len(lst2)-1=2,第一次进入while语句中,if语句条件满足,第二次进入while语句中,if条件不满足,执行else语句,j=2-1=1,第三次进入while语句中,if条件不满足,执行else语句,j=1-1=0,第四次进入while语句中,if条件不满足,执行else语句,j=0-1=-1,退出while循环,while循环一共执行了4次。②若函数中while语句的条件“j>=0”误写为“k>=0”,j是指向lst2的指针,则当lst2的数据已经处理完时,会出问题,故本题应选A(3)total表示总时间,初始值应设置为0,故第一空应为:total=0;找到k等级的链表的表尾,若该等级已存在其他器件,由于器件是按时间升序遍历。因此我们将该器件添加到k 等级链表表尾。通过访问 k等级对应的链表表尾,找到表尾位置 p(p=queinfo[k][1]),然后在链表表尾追加当前器件的索引位置i,完成待处理器件的入队操作,故第二空应为:p= queinfo[k][1];在k 等级链表中,找到最高 k 等级单链表指向的位置 p,p 为单链表中队首器件位置,此处是将p 指向的器件删除,通过更新k等级链表表头 queinfo[k][0],使链表表头指向p 的下一个器件位置,完成删除操作,故第三空应为:queinfo[k][0]=data[p][3]。
8.(2024·浙江·高考真题)某项活动有n个单位(编号1到n)参加,需将员工分成若干个小组,每个小组的人数上限为m,小组编号按新建次序从1开始编号。分组时,首先按单位编号次序依次在各单位内部分组,每m人分配到一个新建小组中,不足m人的剩余员工暂不分配;然后按剩余员工人数由大到小的顺序,依次为各单位剩余员工分配小组。
若某单位剩余员工人数为k,则分配方法为:在已建的小组中查找空位数(该小组还可容纳的人数)大于或等于k的小组,如果找到的小组有多个,则选择空位数最少的小组,将此k人分配到该小组中;如果没有找到,则新建一个小组,将此k人分配到该小组中。
设n为5,m为20,各单位员工人数及单位内部的分组过程如图a所示,各单位剩余员工的分组过程如图b所示。
图a 图b
编写程序:给定各单位编号及员工人数,根据上述方法进行分组处理,按单位编号次序输出各单位所分配的分组编号。请回答下列问题:
(1)由题意可知,若仅将图a中1号单位的员工人数修改为25,然后对图中5个单位重新分组,则1号单位所分配的分组编号为 。
(2)定义如下bubble_sort(lst)函数,参数lst的每个元素由单位编号和剩余员工人数2个数据项构成。函数的功能是根据每个单位的剩余员工人数,对lst进行降序排序。
def bubble_sort(lst):
n = len(lst)
for i in range(0,n-1):
for j in range(n-1,i,-1):
if lst[j-1][1] < lst[j][1]:
tmp = lst[j]
lst[j] = lst[j-1]
lst[j-1] = tmp
if lst[i][1] == 0:
break
return
调用该函数,若lst为[[1,0],[2,0],[3,18],[4,0],[5,19],[6,17]],请回答①和②两个问题。
①虚线框中的程序段第1次执行后,关于lst中的剩余员工人数,下列说法正确的是 (单选,填字母)
A.lst[0][1]数值最小 B.lst[0][1]数值最大 C.lst[5][1]数值最小 D.lst[5][1]数值最大
②虚线框中的程序段执行的次数为 。
(3)实现分组功能的部分Python程序如下,程序中用到的列表函数与方法如图c所示,请在程序中划线处填入合适的代码。
图c
def group(data,m):
n = len(data)
a = []
for i in range(n+1):
a.append([])#a[i]初始为空列表,存放编号为i的单位所分配的分组编号
gnum=0
for i in range(n):#各单位内部分组
while data[i][1] >= m:
gnum += 1
k = data[i][0]
a[k].append(gnum)
①
bubble_sort(data)#根据每个单位的剩余员工人数,对data进行降序排序
b = []
for i in range(m):
b.append([])
i = 0
while i < n and data[i][1] != 0:#对剩余员工分组
②
while j < m and len(b[j])== 0:
j += 1
if j < m:
v = b[j].pop()
else:
gnum += 1
v = gnum
a[data[i][0]].append(v)
③
i += 1
#输出各单位的分组编号,代码略
'''
读取小组人数上限存入m;读取1至n号单位的数据,依次存入列表 data 的 data[0]至data[n-1]中。data[i]包含2个数据项,data[i][0],data[i][1]分别存放单位编号及员工人数,代码略
'''
group(data,m)
【答案】 1,8 B 4 data[i][1]-=m j=data[i][1] b[j-data[i][1]].append(v)
【知识点】典型算法
【详解】本题考查Python程序设计相关内容。分析题目内容,推知:
(1)1号单位的员工人数25,组建1个小组后剩余5人,依据编号分组规则,3号单位组建小组,其中8组不满20人,尚缺6人,可以将1号单位剩余5人分配至3号单位小组,即8组。故本题答案是:1,8。
(2)程序段功能是根据每个单位的剩余员工人数,对lst进行降序排序,则排序后,lst[0][1]为序列最大值,lst[5][1]为序列最小值,故②处答案为:B。虚线框中的程序段执行次数由lst[i][1]是否为0决定,以当前lst为例,j所在for循环分别经过排序将[5,19]、[3,18]、[6,17]放在正确位置后,i值为2,此时,lst[i][1]不为0,i所在for循环使得i取值为3,再执行虚线框中的程序段,此时满足lst[i][1]==0,执行break,跳出循环。所以虚线框中的程序段共执行4次,故③处答案为:4。
(3)for循环实现各单位内部分组,对于第i个单位,当data[i][1]>=m成立时,可以按照分组规则以m为人数标准进行分组,每组m人,每分一组,再判断剩余人数是否满足条件,故④处答案为:data[i][1]-=m。⑤处所在循环对剩余员工分组,j为第i组剩余员工,其初值为data[i][1],故⑤处答案为:j=data[i][1]。⑥根据题中代码,我们需对上面两种情况分类讨论::1、若查找成功,则从体积为j的空位数包b[j]中取一个分组编号v,然后将体积为data[i][1]物品放入到该空位数包对应的分组编号v中。 此时,体积为j的空位数包中分组编号v已不存在b[j]中,但实际上包体积j放入体积data[i][1]后,仍可能会得到一个体积更小的新空位数包,新空位数包体积为j-data[i][1]。 因此,我们更新前i个物品放入后的状态b[0..i],在体积为j-data[i][1]中增加组编号v的新空位数包,表示该组编号v下还可以继续放,更新其空位数体积为:j-data[i][1]。2、若查找失败,则重新分配一个组编号v,此时体积 data[i][1]独占这个包体积,放入后可能还有空位数空间,因此将得到一个体积为m-data[i][1]的新空位数包,结合代码查找失败时,变量j值等同变量m。 因此,本小题答案为:b[j-data[i][1]].append(v)。
试卷第1页,共3页
试卷第1页,共3页
学科网(北京)股份有限公司
$$