1 条题解
-
0
好的,我们先根据前面的 C++ 标程(BFS 解法) 来整理一份详细的文字题解。
题意简述
我们有:
- 两个非负整数 ,初始时 给定。
- 两种操作:
- ,成本 。
- (异或 ,即翻转二进制最低位),成本 。
- 目标:让 变成 ,求最小成本;不可能则输出 。
- 数据范围:,, 个测试用例。
关键观察
-
操作 只会改变 的最低位:
- 若 是偶数(最低位 ),。
- 若 是奇数(最低位 ),。
-
由于只能进行 和 ,且 可能先变大再变小(因为奇数时 会减少 ),因此最终答案的最优路径中, 的值不会超出 太多,但理论上为了用 调整奇偶性,可能会先增加再减少。
-
因为 ,并且奇数 会 ,所以 在最优过程中不会超过 (证明略,但 BFS 开到 足够安全)。
解法思路
这是一个最短路径问题,状态是当前的 值,边有两种:
- ,边权 。
- ,边权 。
由于图很小(节点数最多 ),可以直接用 Dijkstra(边权非负)或 BFS 变种(因为边权不同,优先队列 Dijkstra 更安全)求从 到 的最短路。
算法步骤
- 初始化距离数组 ,,小根堆
(cost, val)。 - 当堆非空:
- 弹出
(cost, val),如果 则跳过。 - 如果 ,可以提前结束(但继续也行)。
- 尝试操作 :如果 且 ,更新并入堆。
- 尝试操作 :,如果 且 ,更新并入堆。
- 弹出
- 最终 为最小成本,若仍为 输出 。
为什么范围开到 ?
考虑最坏情况:。
我们需要通过 让 减小,但 只能发生在奇数 → 偶数(减 )。
为了制造奇数,可能需要先 若干次,所以 会暂时超过 。
但一旦超过 再回来不会更优(可以通过分析证明),因为 。
时间复杂度
- 每个测试用例 BFS/Dijkstra 访问最多 个节点。
- 边数 ,堆操作 。
- 总复杂度 ,完全可行。
样例验证
以样例 1 4 1 2 为例:
- 初始 。
- 路径:$1 \xrightarrow{+1} 2 \xrightarrow{+1} 3 \xrightarrow{+1} 4$,成本 。
- BFS 也会找到同样的结果。
正确性说明
- 因为所有边权为正,Dijkstra 保证第一次弹出 时就是最小成本。
- 范围 足够包含最优路径上的所有中间值(可严格证明:若超过 ,则必能换成更优路径)。
这样,我们就得到了一个正确、高效、易于实现的解法。
- 1
信息
- ID
- 7120
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者