\(\color{black}\texttt{A. 转盘锁}\)
题目描述
给定一个四位转盘锁,每个转盘上都有 \(0\) 到 \(9\) 的数字。数字 \(i\) 的下一个数字是 \((i+1)\bmod 10\),上一个数字是 \((i-1)\bmod 10\)。每次你可以将一段连续的区间全部往上翻或往下翻一个数字。现在给定一个初始时的转盘,求最少需要多少次操作才能达到目标状态。
思路
首先,一个转盘锁 \(abcd\rightarrow efgh\),可以看作 \(0000\rightarrow (abcd-efgh)\bmod 10\)。所以 BFS 预处理从 \(0000\) 到其他所有状态的最短路即可。
代码
#include<bits/stdc++.h>
using namespace std;struct Node {vector<int> v;int dis;
};int T, ans;
string s, t;
queue<Node> que;
map<vector<int>, int> dist;void Record(const vector<int> &v, int dis) {if(dist.count(v)) {return;}dist[v] = dis;que.push({v, dis});
}void bfs() {Record({0, 0, 0, 0}, 0);for(; !que.empty(); ) {auto [v, dis] = que.front();que.pop();for(int i = 0; i < 4; ++i) {for(int j = i; j < 4; ++j) {for(int op : {-1, 1}) {for(int k = i; k <= j; ++k) {v[k] = (v[k] + op + 10) % 10;}Record(v, dis + 1);for(int k = i; k <= j; ++k) {v[k] = (v[k] - op + 10) % 10;}}}}}
}void Solve() {cin >> s >> t;vector<int> v = {(s[0] - t[0] + 10) % 10, (s[1] - t[1] + 10) % 10, (s[2] - t[2] + 10) % 10, (s[3] - t[3] + 10) % 10};cout << dist[v] << "\n";
}int main() {ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);bfs();for(cin >> T; T--; Solve()) {}return 0;
}