深耕专业教研,探索前沿技术
信息技术来源:金华十校2026年4月高三模拟考试

第 15 题

答案与解析

第(1)小题

参考答案

2

同一时刻有订单的店铺,每单加2,不再减1;无订单时才减1,且不低于0。优先级大于5才入榜,小于等于3才退榜;处于4或5时,保留此前的入榜状态。

按图15-3统计各时刻的订单,得到:

时刻 店铺1优先级 店铺2优先级 店铺3优先级 优先推荐名单
0 0 0 0 空
1 0 0 2 空
2 2 0 4 空
3 4 0 6 店铺3
4 3 2 5 店铺3
5 2 4 4 店铺3
6 1 6 6 店铺2、店铺3

店铺3在时刻3入榜,之后虽然降到5、4,但未降到3,仍在名单中;店铺2在时刻6入榜。因此时刻6有2家店铺。

第(2)①小题

参考答案

C

程序分析

def bsort(data): # 列表 data 保存订单数据,每个订单数据为[时刻 t,店铺 id]
    n = len(data)
    c = 0
    for i in range(n - 1):
        for j in range(n - 1 - i):
            if data[j][0] > data[j+1][0]:
                data[j], data[j+1] = data[j+1], data[j]
            elif data[j][0] == data[j+1][0] and data[j][1] > data[j+1][1]:
                data[j], data[j+1] = data[j+1], data[j]
                c += 1

第一个条件比较相邻订单的时刻:左侧时刻较大才交换,使较早的订单向前移动。时刻相同则比较店铺id,左侧id较大才交换,使较小的id向前移动。时刻不同的订单由第一个条件决定次序,店铺id只参与同一时刻内部的比较。

解题思路

两个嵌套循环反复比较、交换相邻订单,内层比较范围逐轮缩小,这是冒泡排序的结构。每条订单为[时刻t,店铺id],两个分支使用不同的交换条件。

因此,时刻是第一排序依据,店铺id是同一时刻内的第二排序依据,两者均按从小到大的顺序排列。

第(2)②小题

参考答案

2

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

c初值为0,且只有“时刻相同、左侧id较大”的elif分支执行c+=1,因此c统计同一时刻内id逆序造成的交换次数。时刻不同的订单交换时,不改变同一时刻订单之间的相对次序,可按原列表分组考察:

时刻 原列表中的id次序 升序次序 计入c的交换次数
1 3 3 0
2 3,1 1,3 1
3 3,1 1,3 1
4 2 2 0
5 2 2 0
6 2,3 2,3 0

c=1+1=2。

第(3)小题

参考答案
  1. tt - post[sid] - 1

  2. st[sid] == False

  3. val[sid] > 3

程序分析

bsort(data)
s = []
st = [False] * (n + 1)
val = [0] * (n + 1)
post = [0] * (n + 1)

bsort按时刻、店铺id升序排列订单,使同一时刻、同一店铺的记录相邻。s初值为空;st、val、post按店铺编号访问,各项分别初始化为False或0。

i = j = 0
while i < m:
    ...
    i = j

i定位当前待处理的第一条订单,j向后寻找本组的结束位置。每轮末尾执行i=j,转入下一组。

while j < m and data[i] == data[j]:
    j += 1
cnt = j - i
tt, sid = data[i][0], data[i][1]

排序后,相同的[时刻,店铺id]记录连续排列。j在记录相同时增加,退出后下标i至j−1属于同一时刻、同一店铺,共cnt=j−i单;tt和sid分别取得该组时刻和店铺编号。

val[sid] -= ①
post[sid] = tt
if val[sid] < 0:
    val[sid] = 0
# 原题修改:新增以下三行,处理无订单期间优先级降至3及以下时的退榜。
if val[sid] <= 3 and st[sid]:
    st[sid] = False
    s.remove(sid)
val[sid] += cnt * 2

先扣减val[sid]并将负值归零,随后按本组订单数增加cnt*2,与优先级的变化规则对应,因此val保存店铺优先级。post[sid]在本轮更新为tt,所以扣减发生时,它保存该店铺上一次有订单的时刻,首次处理时为0。

加上本组订单分数之前,程序先检查扣减后的优先级:若已降到3及以下且st[sid]为True,就将标记置False并从s删除该店铺。这一步先处理无订单期间的退榜,再处理当前订单,保留了先退榜、后重新判断是否入榜的时间顺序。

if val[sid] > 5:
    if ②:
        st[sid] = True
        s.append(sid) # 将 sid 添加到列表 s 的末尾
        k = len(s) - 1
        while s[k] < s[k - 1] and k >= 1:
            s[k - 1], s[k] = s[k], s[k - 1]
            k -= 1

当前订单计分后,优先级超过5才进入入榜分支。满足空②时,将st[sid]置True并把sid加入s;结合前面的退榜操作可知,st记录该店铺在最近一次处理后的入榜状态,s保存相应店铺编号。追加的新编号从表尾逐次向左交换,使s保持升序。其他店铺尚未结算到当前时刻,其状态会在下次有订单时或最终输出前更新。

print("优先推荐店铺名单:")
for sid in s:
    if post[sid] < T:
        val[sid] -= T - post[sid]
    if ③:
        print("店铺", sid)

订单全部处理完后,s中的店铺在各自最后一次订单处理后仍处于入榜状态。post[sid]之后到T没有新订单,需再扣去T−post[sid],由空③判断它是否仍应输出。这里只筛选最终名单,不再修改s;即使扣减结果为负,也会被退榜阈值排除。

填空分析

①

上一次有订单的时刻为post[sid],本次为tt;两次有订单的时刻均不扣分,中间无订单的时刻为post[sid]+1至tt−1,共tt−post[sid]−1个。因此填:

tt - post[sid] - 1

首次处理时post[sid]=0,对应扣除时刻1至tt−1;相邻时刻都有订单时,扣减量为0。

②

外层条件已经保证优先级大于5。若该店铺仍在名单中,不应重复追加;尚未入榜或已经退榜时,st[sid]为False,才需要加入。因此填:

st[sid] == False

③

能进入最后的for循环,说明该店铺在最后一次处理订单后仍在名单中。此后没有订单,优先级只会降低,降到3及以下才退榜,所以最终仍大于3就应输出,填:

val[sid] > 3

这里判断的是已经入榜的店铺是否继续保留,优先级为4或5时也应输出。例如时刻1有3单时优先级为6,时刻2无订单降为5,T=2时仍在名单中。