题目描述
小 Y 有一把五个拨圈的密码锁。如图所示,每个拨圈上是从 0 到 9 的数字。每个拨圈都可以独立旋转,或者与相邻拨圈联动。
每次操作可以选择一个拨圈将其数字加 1 或减 1(模 10),或者选择两个相邻拨圈同时操作。目标是使所有拨圈变为指定目标数字。
给定初始状态和目标状态,求最少需要多少次操作。
输入格式
一行包含 5 个整数,表示初始状态。 下一行包含 5 个整数,表示目标状态。
输出格式
输出一个整数,表示最少操作次数。
解题思路
本题属于典型的广度优先搜索(BFS)问题。由于拨圈数量较少(5 个),每个位置有 10 种可能,总状态空间为 $10^5$,可以通过 BFS 遍历所有可达状态。
- 状态表示:使用字符串或数组存储当前 5 个拨圈的数字。
- 队列管理:将初始状态加入队列,记录步数。
- 去重标记:使用哈希表或数组记录已访问状态,避免重复计算。
- 扩展规则:对当前状态的每个拨圈尝试 +1、-1 操作,若达到目标则返回步数。
参考代码
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <unordered_set>
using namespace std;
int main() {
string start, target;
cin >> start >> target;
queue<pair<string, int>> q;
unordered_set<string> visited;
q.push({start, 0});
visited.insert(start);
while (!q.empty()) {
auto [curr, steps] = q.front();
q.pop();
if (curr == target) {
cout << steps << endl;
return 0;
}
( i = ; i < ; ++i) {
string next = curr;
next[i] = (next[i] - + ) % + ;
(visited.(next) == visited.()) {
visited.(next);
q.({next, steps + });
}
next = curr;
next[i] = (next[i] - + ) % + ;
(visited.(next) == visited.()) {
visited.(next);
q.({next, steps + });
}
}
}
;
}


