GESP七级真题解析:俄罗斯方块中的二维数组模拟与碰撞检测
题面回顾与考场初见很多同学第一次在GESP七级考场里看到“俄罗斯方块”这个大标题第一反应多半是完了这题得写个游戏其实完全不是。七级考纲里明确强调了二维数组模拟、状态判断和边界处理能力俄罗斯方块这道题正是把这些考点包了一层“游戏外壳”本质上是让你处理一个形如二维网格的“拼图下落”过程。我辅导过不少备考七级的学生这道题是2024年3月场次里区分度相当高的一道题。说它难不是因为算法有多深奥而是在短时间内把矩阵变换、碰撞检测、落定位置这三个环节全部写对确实暴露了不少基本功问题。先说结论如果你能熟练掌握“先裁剪形状、再从高处逐行试探下落”的思路这道题就是一道送分题如果上来就想一步到位算出最终落点反而容易把自己绕晕。这篇文章我会按考场上最稳妥的解题路径来拆从题目建模开始讲清楚为什么推荐“逐行试探”而不是“公式定位”再给出完整的C实现最后专门列几个我批改学生代码时反复见到的经典错误。全文代码均基于我按当年真题考点还原的模拟版本思路与官方标准解法一致细节部分做了适配说明。1. 题目建模与核心思路拆解1.1 题面到底让你做什么先明确题目给定的输入结构。典型的GESP七级俄罗斯方块题长这样输入一个N行M列的01矩阵代表游戏地图1表示该格已有方块0表示空格再输入一个h行w列的01矩阵代表当前下落的方块形状方块从地图正上方开始下落初始列位置由题目给定通常是居中对齐或指定某一列方块只能竖直向下移动不能旋转、不能左右移动当方块在下一时刻会与地图中的已有方块或地图底部发生重叠时停在当前位置输出方块落定后的完整地图状态有的变体还会要求统计并消除满行后再输出。这道题看上去是“游戏模拟”实际考查的是最基础的坐标系统理解和二维矩阵操作能力。七级考试时间有限题目不会要求你实现完整的俄罗斯方块玩法——旋转、消行、计分这些统统去掉了就留下最干净的一个物理过程一个矩形像素块从天而降直到碰到底部或已有堆叠。1.2 为什么推荐逐行试探而不是一步到位拿到这个题第一感觉是怎么快速算出最终停在第几行。有一种思路是遍历方块的每个有效格子找它下方最近的障碍物或地图底部然后取最小可行距离作为整体下落距离。听起来很高效但实际写起来坑很多方块内部可能有空洞不同列的障碍物高度不同还要考虑方块自身格子之间的遮挡关系。一旦某个格子定位出现偏差整个落点就错了而且肉眼很难排查。我推荐的做法是逐行试探从第0行开始依次判断“方块放在当前行是否合法”合法就继续往下试探直到下一行不合法为止。这种写法的优点是逻辑直观——你不需要为“最近障碍距离”设计额外数据结构每一行都完整走一遍重叠检测就行。时间复杂度是O(N×h×w)地图最大规模就算到100×100方块形状10×10最坏也只需10万次格子判断完全可以在1秒内跑完。1.3 裁剪形状矩阵是第一个关键步骤这里有一个新手极其容易忽略的处理方块形状矩阵的h行w列未必全部有效。比如题目输入的是3×3矩阵0 0 0 0 1 0 0 0 0实际有效形状只是一个1×1的格子。如果不裁剪直接拿3×3的矩形去做碰撞检测方块下落到某个位置时形状矩阵里那些为0的格子也会参与越界和重叠判断——在单纯重叠检测中这不会出大问题因为0不会触发碰撞但你如果用了“遍历矩阵找1的下标”来算落点这些空白边缘就会让计算结果偏差巨大。更关键的是很多题目变体在描述方块形状时矩阵四周确实存在0填充这时如果不把无效行列裁掉你在计算方块占据的列范围、对齐初始位置时就会出错。我的习惯是读入形状后立刻做一次裁剪找到所有包含1的行取最小行号和最大行号找到所有包含1的列取最小列号和最大列号将有效区间截取出来作为新的形状矩阵。这样做的好处是后续所有代码都基于“最小有效外接矩形”来处理边界清晰逻辑统一。2. 碰撞检测整道题的心脏2.1 如何判断方块能否放在某一行假设地图是board[N][M]裁剪后的形状是shape[H][W]当前尝试放置的左上角行为r。判断过程就是逐一检查形状矩阵里每个值为1的格子在地图上对应位置是否越界或与已有方块重叠bool canPlace(int r) { for (int i 0; i H; i) { for (int j 0; j W; j) { if (shape[i][j] 1) { int nr r i; int nc col j; if (nr 0 || nr N || nc 0 || nc M) return false; if (board[nr][nc] 1) return false; } } } return true; }注意这里有一个容易弄反的逻辑你是在试探“方块放到这一行是否合法”所以只要发现任何一个有效格子与地图的1重叠或者超出地图边界就立即返回false。很多同学会把条件写成“地图这一格是0才放得下”这在逻辑上等价的但代码上建议用“发现冲突就退出”的模式调试时思路更顺。2.2 下落主循环的终止条件确定了canPlace函数之后主循环非常简单int curRow 0; while (curRow H N canPlace(curRow)) { curRow; } // 出循环时curRow是第一个放不下的行方块应停在curRow-1 curRow--;这个循环有一个隐藏的边界细节当方块整体已经超出地图下边界时也必须停止。所以循环条件里要写curRow H N不能只靠canPlace去判断否则形状矩阵底部超出地图后内层越界检查会返回false但那时方块已经“穿地”了落点位置就不对。我第一次给学生讲这个细节时有学生反问那如果方块落下来时底部还没到地图边界但某个格子已经和地图上的方块重叠了循环是不是会提前退出对这个逻辑天然覆盖了“碰到已有方块”的情形。所以整个下落模拟只需要关注一件事下一行是否放得下放得下就继续走。2.3 落定后如何把形状写入地图找到最终行位置后把形状矩阵中的1逐一覆盖到地图对应坐标for (int i 0; i H; i) { for (int j 0; j W; j) { if (shape[i][j] 1) { int r finalRow i; int c col j; board[r][c] 1; } } }这一步是纯赋值操作基本不会出错。唯一要注意的是如果题目还要求消行必须在地图更新完方块之后、输出之前完成消行处理顺序不能颠倒——先落定再消行这是符合物理过程的。3. 完整实现与细节优化3.1 我按真题还原的参考代码下面是我按2024年3月GESP七级俄罗斯方块考点还原的完整C实现代码风格偏竞赛向核心函数就三个裁剪形状、判断放置、执行落定。#include iostream using namespace std; const int MAXN 105; int board[MAXN][MAXN]; int shape0[MAXN][MAXN]; int shape[MAXN][MAXN]; // 裁剪后的形状 int H, W, N, M, col; // 裁剪形状矩阵去掉全0的行和列 void trimShape() { int minR H, maxR -1, minC W, maxC -1; for (int i 0; i H; i) { for (int j 0; j W; j) { if (shape0[i][j] 1) { if (i minR) minR i; if (i maxR) maxR i; if (j minC) minC j; if (j maxC) maxC j; } } } if (maxR -1) { // 形状全为0极端情况 H 0; W 0; return; } int newH maxR - minR 1; int newW maxC - minC 1; for (int i 0; i newH; i) { for (int j 0; j newW; j) { shape[i][j] shape0[minR i][minC j]; } } H newH; W newW; } // 判断方块放在第r行左上角行号是否合法 bool canPlace(int r) { for (int i 0; i H; i) { for (int j 0; j W; j) { if (shape[i][j] 1) { int nr r i; int nc col j; if (nr 0 || nr N || nc 0 || nc M) return false; if (board[nr][nc] 1) return false; } } } return true; } int main() { cin N M; for (int i 0; i N; i) { for (int j 0; j M; j) { cin board[i][j]; } } cin H W; for (int i 0; i H; i) { for (int j 0; j W; j) { cin shape0[i][j]; } } cin col; // 初始列位置题目给定 trimShape(); int curRow 0; while (curRow H N canPlace(curRow)) { curRow; } curRow--; // 写入地图 for (int i 0; i H; i) { for (int j 0; j W; j) { if (shape[i][j] 1) { board[curRow i][col j] 1; } } } // 输出 for (int i 0; i N; i) { for (int j 0; j M; j) { cout board[i][j]; if (j M - 1) cout ; } cout endl; } return 0; }这段代码里我用了两个数组分别存原始形状和裁剪后形状一是为了代码可读性二是避免在原数组上做覆盖时下标混乱。实际竞赛中可以只用一个数组在trim时用另一个临时数组接住结果再拷贝回来效果一样。3.2 为什么列位置固定后就不用考虑左右越界题目规定方块只能竖直下落不能左右移动所以你在读入初始列位置col之后方块的水平位置就锁死了。这也意味着canPlace里的列坐标nc col j是一个固定值不需要在循环里额外调整。但有一个细节要小心题目给的col是“方块矩阵左上角在地图中的列号”还是“方块图形裁剪后的左上角列号”不同题目描述可能不同。如果你的裁剪前后矩阵宽度不一致col的语义变化会直接导致形状画偏。稳妥做法是在读入col后、裁剪形状前先统一语义——我一般约定col表示“裁剪后形状的左上角列号”。如果题目给的col是相对原始矩阵的就需要根据裁剪时去掉的左边界列数做一次偏移修正。这个坑我在实际辅导中见过好几个人踩。比如原始形状是5×5有效部分集中在第2到第4列题目给的col是1那么裁剪后形状的有效列范围是[2,4]实际左上角列号是123。如果直接用1去放置形状就整体左移了两格答案全错。3.3 关于全0形状的极端情况理论上题目不会出全0形状但竞赛代码讲究鲁棒性我在trimShape里专门加了如果maxR-1就返回的防御分支。如果忘了这个分支后面canPlace里的H和W变成0循环条件curRow H N恒成立canPlace恒返回truewhile循环会无限跑下去直到curRow溢出。这种极端情况虽然不常见但加上防御代码成本几乎为零养成习惯没坏处。4. 考场上容易踩的坑与排查实录4.1 形状裁剪遗漏导致的隐性问题我和几个备考学生复盘2024年3月这题时发现最大的失分点不是算法不懂而是形状裁剪没做或者做错了。有个学生的代码逻辑是先遍历形状矩阵把所有为1的格子的相对行列存到vector里然后直接用这些相对坐标去做碰撞检测。听起来没问题对吧但他存的相对坐标是相对原始矩阵的比如原始矩阵是5×5有效格子只在(2,1)和(2,2)两格他存储的相对坐标就是(2,1)和(2,2)。在碰撞检测时他直接用这两个坐标去地图上偏移等于把形状左上角当成了(0,0)对应的位置但实际上原始矩阵左上角(0,0)是空白格。结果就是方块实际显示出来的位置比预期偏下两行、偏右一列。这种错误视觉上非常隐蔽如果样例给的刚好是比较规整的中心对称形状甚至能侥幸通过小数据测试但大数据一跑就露馅。解决方案就是先裁剪再操作。裁剪后相对坐标的(0,0)就是有效形状的左上角所有后续偏移都建立在这一基础上根本不会产生上述偏差。4.2 边界条件里的“差一错误”while循环的终止条件是本题最容易差一行的地方。我见过的错误写法有两种第一种是while (canPlace(curRow)) curRow;这种写法在方块落到地图底部时curRow会一直加到超出边界然后canPlace因为nr N返回false而退出但此时curRow已经是“第一个放不下的行”理论上最终行是curRow-1。如果后面写map时直接用了curRow就会越界写坏地图。我建议在循环条件里显式加上curRow H N这样即使形状底部还没碰到障碍循环也会在整体越界时停止。第二种是int curRow 0; while (canPlace(curRow 1)) curRow;这种写法的本意是试探下一行但起始时curRow0如果方块放在第0行就不合法while直接跳过curRow保持0然后写入地图时会放在第0行——但正确答案应该是在第0行尝试失败后停在上方某个“不可见”的位置。这个逻辑边界非常容易出错我不推荐这种风格。统一推荐定义curRow为“当前试探的左上角行号”从0开始递增每递增一次都做全量合法性检查循环自然终止后停在前一个合法行。4.3 样例过但交上去零分的典型案例有一类代码是样例能过、大数据全错的典型问题出在存储方式上。有些同学图省事把地图存成vectorvector 然后直接用push_back去扩展但不同行的列数不一致后面访问board[i][j]时就会访问到不存在的位置行为未定义。正确的做法是用定长二维数组或者vector预先resize好行列。我在参考代码里直接用const int MAXN固定数组大小简单可靠。如果为了更灵活的输入也可以用vectorvectorint board(N, vectorint(M));重点是保证数据结构的维度确定不要在地图输入过程中动态改变每一行的长度。4.4 关于消行变体的处理有些回忆版题目会在“输出地图”之前加一步消除所有铺满1的行上方整体下移。这属于简单变体但很多同学在消行排序上犯错。正确做法是先扫描每一行如果整行全是1就标记为待消除然后从下往上遍历遇到标记行就跳过不写非标记行按顺序填充到新地图的底部。注意一定要从下往上处理否则上方行下移时可能覆盖还没判断的旧数据。int writeRow N - 1; for (int i N - 1; i 0; i--) { bool full true; for (int j 0; j M; j) { if (board[i][j] 0) { full false; break; } } if (!full) { for (int j 0; j M; j) { board[writeRow][j] board[i][j]; } writeRow--; } } for (int i writeRow; i 0; i--) { for (int j 0; j M; j) { board[i][j] 0; } }这个技巧的核心在于先消除满行再整体下移顺序不能反。如果你想先下移再消除下标会乱掉。5. 从这道题延伸出来的备考建议5.1 为什么七级考试爱出这种“伪游戏题”GESP七级的定位是“提高级”考查的重点是复杂模拟、基础动态规划和简单图论。俄罗斯方块看似游戏实际上把复杂模拟的几个典型难点都覆盖了形状数据的前处理裁剪、多条件判断的碰撞检测、坐标边界控制、以及可选的消行操作。这类题能很好地区分“背过模板”和“真正理解坐标系统”的学生。准备七级的过程中不要光刷纯算法题二维矩阵模拟题至少要做透三五道。我建议找“方块下落类”的题目集中练比如不同形状的拼图放置、不同下落规则的转换练完你对“矩阵坐标、偏移量、边界条件”这三个概念会有质的提升。5.2 自己出测试数据的方法这题调试时可以自己生成小数据来验证。比如N4M4地图全0方块是2×2的全1矩阵col0那答案应该就是方块落到底部也就是占据第2行到第3行。用手算验证之后再构造一个地图已有方块阻挡的情形手动推一遍落点。这种“手算小数据”比盲目用样例测高效得多。我调试这类模拟题还有一个习惯在代码里临时加一个调试函数打印当前试探行和碰撞位置void debugPrint(int r) { cout Try row r : ; cout (canPlace(r) ? ok : blocked) endl; }在while循环里调用它观察方块在哪一行第一次被挡就能快速定位是边界问题还是碰撞逻辑问题。调试完记得删掉或注释别影响最终提交。5.3 考场时间分配与检查顺序这道题如果思路顺畅半小时内写完绰绰有余。但如果卡住了别死磕超过四十分钟——七级后面的题往往还有更大的分值。我的建议是先写一个最朴素的逐行试探版本通不过样例就说明基本逻辑有严重问题这时候检查顺序是输入有没有读错特别是col是不是在形状之前读入的形状矩阵有没有裁剪裁剪后的H和W是否符合直觉canPlace里的越界判断有没有写反while循环退出后写入地图用的行号是否合法。按这个顺序排查百分之八十的错误都能定位到。6. 我个人实操中的一些体会这道题我前前后后在不同场合讲过很多遍每次讲都有新的感触。最核心的一条是不要把“模拟题”想得太高级它就是老老实实地把题面描述的每一步翻译成代码。方格下落就一格一格地试探碰到障碍就停在上一格。所有试图“一步到位”的聪明做法都容易在细节上反噬你。另外我特别想强调一点二维矩阵题的调试一定要养成“可视化”的习惯。程序里打印两个数字、几个下标有时候真不如直接打印出地图长什么样来得直观。我见过的学生里凡是愿意花30秒写一个打印函数的人排查速度比盯着变量发愁的人快一倍不止。如果你正在准备GESP七级这道俄罗斯方块题值得反复做两遍第一遍独立写完第二遍在理解基础上优化代码结构。两遍下来你会发现以后再遇到任何“模拟某个物理过程”的题心里都有底了。

相关新闻

Qt窗口体系全解析:从QMainWindow到五大组件

Qt窗口体系全解析:从QMainWindow到五大组件

我最早用Qt做桌面工具的时候,最容易被一堆窗口概念绕晕:菜单栏、工具栏、状态栏、浮动窗口、对话框,每个看起来都是一个“窗口”,但它们在QMainWindow里的职责和生命周期完全不一样。菜单栏挂在窗口顶部,工具栏可以拖来…

2026/10/19 7:14:11 阅读更多 →
YOLOv7量化部署实战:PTQ/QAT训练到TensorRT C++推理全链路

YOLOv7量化部署实战:PTQ/QAT训练到TensorRT C++推理全链路

简介:从YOLOv7模型的PTQ后训练量化与QAT量化感知训练,到基于TensorRT的C推理部署,这份下载包面向需要在GPU端高效落地检测模型的算法工程师与嵌入式开发人员。压缩包共134个文件,约35.14MB,包含35个Python脚本&#xf…

2026/10/19 7:13:11 阅读更多 →
前端绘图组件实战:从架构拆解到交互实现的完整指南

前端绘图组件实战:从架构拆解到交互实现的完整指南

diagram-design 这个项目,说起来其实是被实际业务逼出来的。当时我们团队在做一款业务中台类的产品,开发和交付过程中需要大量绘制架构图、流程图、部署拓扑图,但工具散落在各处:有人用通用绘图软件,有人直接在文档里用…

2026/10/19 7:13:11 阅读更多 →

最新新闻

基础模型重塑广告竞价环境建模:Bid2X 解读

基础模型重塑广告竞价环境建模:Bid2X 解读

广告竞价这个领域,真正难的不是“怎么出价”,而是“出价之后到底会发生什么”。KDD25 这篇 Bid2X,标题里最抓人的就是“环境建模”这四个字——它把视角从策略本身拉远到了策略所处的整个动态拍卖市场。基础模型视角的引入,让环境…

2026/10/19 7:59:32 阅读更多 →
Linux下Gitee托管实战:从SSH配置到高频报错排查

Linux下Gitee托管实战:从SSH配置到高频报错排查

年前有个朋友从 Windows 桌面端切到 Linux 环境干活,第一天就差点把键盘拍碎——他在 Gitee 上建好了仓库,本地也写好代码了,结果对着那个黑底白字的终端窗口发了好一会儿呆,完全不知道该敲什么。后来他问我,Gitee 在 …

2026/10/19 7:59:32 阅读更多 →
LSTM财务因子选股:时间序列建模与A股非平稳数据实战

LSTM财务因子选股:时间序列建模与A股非平稳数据实战

简介:本资源是一套基于LSTM神经网络的财务因子选股预测模型完整实现,专为计算机、人工智能及财经交叉方向的本科生毕业设计与课程设计打造,面向AI、自动化、电子信息等专业学生及初入量化领域的学习者,解决金融时序数据建模与股票…

2026/10/19 7:59:32 阅读更多 →
室内墙面缺陷检测实战:VOC/YOLO双格式数据集与目标检测训练要点

室内墙面缺陷检测实战:VOC/YOLO双格式数据集与目标检测训练要点

做了几年计算机视觉相关的工作,我接过不少“看着简单、做起来抓狂”的项目,墙面缺陷检测就是其中一个。前段时间参与一个旧房翻新前评估的项目,需要统计室内墙面的剥落、污渍和滴痕分布,我一开始天真地想拿通用目标检测模型直接跑…

2026/10/19 7:59:32 阅读更多 →
MSP432+OpenMV寻迹小车控制方案:从寄存器到PID调优

MSP432+OpenMV寻迹小车控制方案:从寄存器到PID调优

简介:2022年电子设计竞赛C题江苏省赛区一等奖的完整工程资料,主控采用MSP432,适合电赛备赛学生、嵌入式开发者与机器视觉入门者参考。作品围绕主从双车寻迹与OpenMV视觉导航展开,包含主车图像处理、停止线识别、障碍物测距以及双车…

2026/10/19 7:59:32 阅读更多 →
U8G2 OLED中文显示全攻略:字体包安装与编译配置

U8G2 OLED中文显示全攻略:字体包安装与编译配置

简介:本资源是面向Arduino嵌入式开发者的U8G2中文字体定制工具包,专为解决OLED/SSD1306等小型显示屏在U8G2库中无法直接显示中文的痛点而设计。包内集成GUI字体生成工具GUITool及完整u8g2-master源码,支持用户自定义字库提取、BDF格式转换与C…

2026/10/19 7:58:32 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →