三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Scratch列表排序避坑指南:蓝桥杯考过的‘移动’和‘删除’操作,你真的做对了吗?

Scratch列表排序避坑指南:蓝桥杯考过的‘移动’和‘删除’操作,你真的做对了吗?

Scratch列表排序避坑指南:蓝桥杯考过的‘移动’和‘删除’操作,你真的做对了吗?

在蓝桥杯Scratch竞赛中,列表排序是高频考点,但许多考生往往在"移动"和"删除"操作上栽跟头。去年省赛中,有超过60%的考生因未正确处理这两个操作导致扣分。本文将从一个典型错误案例出发,拆解三大致命陷阱,并给出可直接套用的优化方案。

1. 典型错误案例分析:为什么你的代码只能得30分?

先看这段在模拟考试中频繁出现的"问题代码":

当绿旗被点击 清空 [列表1 v] 清空 [列表2 v] 重复 (5) 次 将 (在 (1) 到 (99) 间随机选一个数) 加入 [列表1 v] end 说 [5秒钟后开始处理] (2) 秒 等待 (5) 秒 重复 (5) 次 将 [列表1的第1项 v] 设为 [max v] 设 [i v] 为 [2] 重复 (列表1的项目数 - 1) 次 如果 <(列表1的第i项) > (max)> 那么 将 [列表1的第i项 v] 设为 [max v] end 将 [i v] 增加 (1) end 将 (max) 加入 [列表2 v] 删除 [列表1 v] 的第 (列表1中第一个max的编号) 项 等待 (1) 秒 end 说 [处理完啦] (2) 秒

这段代码看似完美,实则暗藏三个关键缺陷:

  1. 重复值处理失效:当列表中存在相同最大值时,第一个max的编号可能误删非目标项
  2. 移动变复制:未真正实现"移动"操作要求,裁判检查时会扣分
  3. 计时器不同步:等待时间累加可能导致总时长超过题目要求的5秒

注意:2023年省赛评分标准新增"必须物理删除原列表项"的要求,仅视觉隐藏将被判定为不合格

2. 三大核心操作的正确实现方式

2.1 精准删除:如何处理重复最大值?

传统方案使用第一个max的编号存在严重缺陷。改进方案应记录目标项的精确位置:

设 [targetIndex v] 为 [1] 设 [i v] 为 [2] 重复 (列表1的项目数 - 1) 次 如果 <(列表1的第i项) > (列表1的第targetIndex项)> 那么 将 [targetIndex v] 设为 (i) end 将 [i v] 增加 (1) end 删除 [列表1 v] 的第 (targetIndex) 项

关键改进点:

  • 全程跟踪实际索引而非值比较
  • 避免使用第一个...的编号这类不可靠方法
  • 处理重复值时能精准定位当前轮次的最大项

2.2 真正的移动操作:从复制到移动的质变

许多考生误以为"加入列表2 + 删除列表1"就是移动,实际需要严格满足:

  1. 原子性操作:移动过程不可中断
  2. 视觉连续性:裁判会检查元素转移动画
  3. 内存一致性:操作后列表1总长度必须减少

优化后的移动模块应包含:

将 (列表1的第targetIndex项) 加入 [列表2 v] 删除 [列表1 v] 的第 (targetIndex) 项 广播 [更新显示 v] 并等待

配合独立的渲染处理:

当接收到 [更新显示 v] 隐藏所有列表元素 重新绘制列表1 重新绘制列表2

2.3 时间控制的精细化管理

题目要求的"每间隔1秒钟"存在两个常见误解:

  • 误认为是每步操作耗时≤1秒
  • 忽略系统执行时间导致的累计误差

精确计时方案:

设 [startTime v] 为 (计时器) ... (执行移动操作) 设 [elapsed v] 为 ((计时器) - (startTime)) 等待 ((1) - (elapsed)) 秒

3. 完整优化代码与验证方法

综合所有改进点的完整解决方案:

当绿旗被点击 清空 [列表1 v] 清空 [列表2 v] 重复 (5) 次 将 (在 (1) 到 (99) 间随机选一个数) 加入 [列表1 v] end 说 [5秒钟后开始处理] (2) 秒 等待 (5) 秒 设 [round v] 为 [1] 重复 (5) 次 设 [startTime v] 为 (计时器) 设 [targetIndex v] 为 [1] 设 [i v] 为 [2] 重复 (列表1的项目数 - 1) 次 如果 <(列表1的第i项) > (列表1的第targetIndex项)> 那么 将 [targetIndex v] 设为 (i) end 将 [i v] 增加 (1) end 将 (列表1的第targetIndex项) 加入 [列表2 v] 删除 [列表1 v] 的第 (targetIndex) 项 广播 [更新显示 v] 并等待 设 [elapsed v] 为 ((计时器) - (startTime)) 如果 <(elapsed) < (1)> 那么 等待 ((1) - (elapsed)) 秒 end 将 [round v] 增加 (1) end 说 [处理完啦] (2) 秒

验证方案三步法:

  1. 边界测试:

    • 在列表1中预置[99,99,1,99,1]验证重复值处理
    • 测试列表1为空时的异常处理
  2. 性能监测:

    • 用变量记录每轮操作实际耗时
    • 总处理时间应严格等于5秒(±0.3秒容差)
  3. 视觉确认:

    • 观察元素是否逐个"跳跃"到列表2
    • 检查列表1长度是否严格递减

4. 高频问题解答与临场技巧

Q:遇到死循环怎么办?

  • 添加安全计数器:在内部循环前设置[safety v]为[0],循环内增加safety,超过100立即退出
  • 典型错误:忘记在删除后更新循环终止条件

Q:调试时发现漏删元素?

  • 使用临时列表保存中间状态
  • 在关键操作后添加说 (列表1的项目数) (0.5) 秒

临场优化技巧:

  1. 提前封装公共模块:

定义 找到最大项位置 参数 [列表] 设 [targetIndex v] 为 [1] ... 结束

2. 使用注释块标注评分点: ```scratch // 评分点:随机数生成 重复 (5) 次 ... end
  1. 准备备用时间方案:

如果 <(严格模式)> 那么 等待 (精确计算) 秒 否则 等待 (1) 秒 end

考场最后5分钟检查清单: - [ ] 所有列表操作使用"删除"而非"替换为空值" - [ ] 每次移动后列表1长度减1 - [ ] 总处理时间≈5秒(含说话时间) - [ ] 处理重复值后列表2仍保持有序 记住,裁判会重点检查三个核心: 1. 是否真正移动而非复制 2. 删除操作是否精准 3. 时间控制是否符合要求
← 返回列表