第 12 题
答案与解析
本题解析
B
程序分析
n = len(money); index= [0] * 100
p1 = 0; p2 = 0; k = 3
ans = []
for i in range(n):
...i依次取0至n-1,逐小时处理营业额。k=3表示每个窗口包含3小时,处理下标i时,完整窗口覆盖i-2至i;i达到2时才形成第一个完整窗口。index预留100个存储位置,p1、p2均从0开始。
if p1 != p2 and index[p1] <= i - k:
①当前窗口的左边界为i-k+1,条件将index[p1]与它前面的下标i-k比较,用于检查窗口左侧的边界。这里只在p1与p2不相等时进行比较。
while p1 != p2 and money[index[p2 - 1]] <= money[i]:
②money[index[p2-1]]把index中保存的值用作money的下标,再读取对应的营业额,由此可确定index保存的是原列表的下标。回看前一个条件,index[p1]<=i-k就是检查一个已保存的下标是否离开当前窗口。
while则比较index[p2-1]对应的营业额与当前营业额money[i],旧值小于或等于当前值时进入循环。
③
p2 += 1
if i >= k - 1:
ans.append(money[index[p1]])③之后p2加1;形成完整窗口时,从index[p1]对应的位置读取结果。结合前面的index[p2-1]访问,可确定候选下标保存在index的有效区间[p1,p2)中:p1指向队首,p2指向队尾后的空位,二者相等表示队列为空。
要从队首取得窗口最大值,补全程序时需要及时排除过期下标,并使队列中的下标递增、对应营业额递减。这些关系由后续三个空共同维护。
填空分析
①
队首下标不大于i-k时,已离开当前窗口。将队首位置后移一格即可移除它,填写p1 += 1。窗口每轮只右移一小时,候选下标按递增顺序保存,因此每轮至多新过期一个队首,用if检查一次即可。
②
当队尾候选的营业额不大于当前值时,当前数据的下标更大、离开窗口更晚,营业额又不小于旧候选。在旧候选仍有效的后续窗口中,当前数据都能替代它。
因此从队尾删除旧候选,填写p2 -= 1。while连续删除,直到队列为空或队尾营业额大于当前值;营业额相等时保留较新的下标。
③
完成两端处理后,将当前小时的下标i写入队尾后的空位p2,填写index[p2] = i。随后p2 += 1将该位置纳入有效区间。index[i]是辅助数组中的内容,不是当前小时的下标。
按此处理,五个完整窗口的最大值依次为980、900、900、950、950。
问题反馈
解析有疑问或显示异常?请先复制题目信息,再打开反馈表单填写。
题目编号:2026_04_G3_jiaxingermo_q012
