题解:B4400 [蓝桥杯青少年组国赛 2025] 第五题
闲话
板题,有一定码量和小细节(但是写起来很快,对称的复制粘贴即可),在这种只有
因此虽然思路简单,放个 T5 还是合适的。
题意
简要题意:有三个牛奶瓶 A、B、C,容积分别为 v,x,y 升,其中最开始 A 灌满了 v 升,B、C 没有牛奶。
每次操作可以任选两个瓶子倒牛奶:
- 如果可以倒满那就倒满。
- 否则全部倒入。
求是否可能让其中一个瓶子恰好有 -1。
做法
首先过掉一部分无解的情况,如果
鉴于数据范围很小,那当然是考虑搜索、枚举啦。稍微有些经验应该能看出来这是道经典的 BFS 入门练习题。
BFS
的做法是,我们维护一个状态队列,每次不断从队首得到新的状态然后将队首出队。如果队首已经有满足情况的就直接结束了,否则继续搜索。初始状态当然是
接着,我们模拟题目中的倒牛奶过程,即 A 倒入 B、A 倒入 C、B 倒入
C,然后每种操作再分两类讨论。由于大差不差的,直接复制粘贴 3 组
但是这样子会超时的!考虑如下情况:
1 | 6 2 1 |
第一次,我们将 A 倒入 B,此时 A 还剩
第二次,我们将 B 倒入 A,此时 A 有
哎这怎么又回去了?
我们发现我们需要存下来已经搜索过的状态,开一个三维数组记录即可(这也是为什么这题数据范围这么小,大一些开三维就 MLE 了)。
如果之前搜索过了就不用继续搜了(因为只会搜以前搜过的状态,反而步数更多了不优,某种意义上这也算是一个简单的最优性剪枝)。
最后,注意如果状态队列空了但是还没有结果那也是无解的,仍然返回
-1。
然后就结束啦!
DFS 也差不多,也可以做,也需要维护一个状态数组,只不过从队列改成递归搜索就好啦!
代码
赛场 ACCode
图片版:
1 |
|
如有除注释以外的差异以图片为准,文字版可以通过。
AC 记录:https://www.luogu.com.cn/record/233679115。
DFS 的也有:
ACCode with 注释
1 |
|
AC 记录:https://www.luogu.com.cn/record/233894967。
提示:memset
会对数组中的每一个元素赋值,三维数组这么大当然时空也会超级大(见这篇帖子),因此不建议使用
memset 初始化而是判断步数是否为 0。此处感谢
@ETO_NOI
的提醒。
完结撒花!
提示:这里情况比较多,空行区分和注释可以大幅减少 debug 的时间和代码阅读难度,相比于花大量的时间调不可读的代码甚至比赛结束也做不完,敲它们的时间是非常划算的。
推荐练习
P1135 奇怪的电梯。和这道题差不多,但是状态要少很多(因为只有向上和向下两种情况)因此要简单一丢丢。
- 标题: 题解:B4400 [蓝桥杯青少年组国赛 2025] 第五题
- 作者: Leo2011
- 创建于 : 2025-08-29 11:06:53
- 更新于 : 2025-11-18 16:00:59
- 链接: https://www.leo2011.eu.org/2025/0829caa27ec3.html
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。









































































































































































