链接:
题意:
有一个4位数字的密码锁,一次操作你可以选择连续的若干位同时向上或向下旋转一位,现问你从一个状态变换到另一个状态的最少操作次数
思路:
- 化繁为简,首先可以想到把所有的 \(a_0a_1a_2a_3 -> b_0b_1b_2b_3\) 转换为 \(0000 -> c_0c_1c_2c_3\),其中 \(c_0c_1c_2c_3\) 为 \(a_0a_1a_2a_3 -> b_0b_1b_2b_3\) 每一位数字正向(或逆向)移动的次数
- 本质上是求一个起点到其他所有点的最短路,且每条边边权为1,可以用 \(BFS\) 求解【这里没想到】
code
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define DEBUG
#define debug(x) cerr << #x << " = " << x << "\n";
using db = long double;
using ll = long long;
// head
// 每个状态有20种移动方式
int d[20][4] = {
{0, 0, 0, 1},
{0, 0, 1, 0},
{0, 1, 0, 0},
{1, 0, 0, 0},
{0, 0, 1, 1},
{0, 1, 1, 0},
{1, 1, 0, 0},
{0, 1, 1, 1},
{1, 1, 1, 0},
{1, 1, 1, 1},
{0, 0, 0, -1},
{0, 0, -1, 0},
{0, -1, 0, 0},
{ -1, 0, 0, 0},
{0, 0, -1, -1},
{0, -1, -1, 0},
{ -1, -1, 0, 0},
{0, -1, -1, -1},
{ -1, -1, -1, 0},
{ -1, -1, -1, -1},
};
// dist数组存最短路
unordered_map<string, int> dist;
void bfs() {
queue<string> q;
q.push("0000");
dist["0000"] = 0;
while (!q.empty()) {
auto t = q.front();
q.pop();
for (int i = 0; i < 20; i++) {
string tmp = "0000";
for (int j = 0; j < 4; j++) {
tmp[j] = (t[j] - '0' + d[i][j] + 10) % 10 + '0';
}
// debug(tmp);
if (!dist.count(tmp)) {
dist[tmp] = dist[t] + 1;
q.push(tmp);
}
// debug(dist[tmp]);
}
}
}
void solve() {
string s1, s2;
cin >> s1 >> s2;
string s = "0000";
// 0000 -> C0C1C2C3
for (int i = 0; i < 4; i++) {
s[i] = (s2[i] - s1[i] + 10) % 10 + '0';
}
// debug(s);
cout << dist[s] << "\n";
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(nullptr); // debug调试注释,提交代码要有
bfs();
int T = 1; cin >> T;
for (int cases = 1; cases <= T; cases++) {
solve();
}
return 0;
}
标签:tmp,10,dist,Luggage,int,Lock,2021,debug,0000
From: https://www.cnblogs.com/Silly3kidZ/p/17058627.html