双向广度优先搜索,本来是想哪个节点少扩展哪个,但是有一个问题,就是有可能上端的x层节点扩展出x+1层,下端的y层扩展出y+1层,这两个+1层有重合,便直接跳出,输出x+y+1,这样可能导致错误,因为x层节点并没有完全扩展完毕,很可能接下来要扩展的x层节点会扩展出的x+1层节点直接与y层节点重合。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
using namespace std;
struct Node
{
int lock[4];
int depth;
}s, e;
int qnum[3], ans;
int hash[3][10][10][10][10];
void getin(int a[], char *st)
{
for (int i = 0; i < 4; i++)
a[i] = st[i] - '0';
}
bool hashit(Node &a, int flag)
{
if (hash[flag][a.lock[0]][a.lock[1]][a.lock[2]][a.lock[3]] == -1)
{
hash[flag][a.lock[0]][a.lock[1]][a.lock[2]][a.lock[3]] = a.depth;
if (hash[3 - flag][a.lock[0]][a.lock[1]][a.lock[2]][a.lock[3]] != -1)
ans = a.depth + hash[3 - flag][a.lock[0]][a.lock[1]][a.lock[2]][a.lock[3]];
return true;
}
return false;
}
void extend(queue <Node> &q, int flag)
{
qnum[flag]--;
Node temp = q.front();
//printf("%d %d %d %d %d\n", temp.depth, temp.lock[0], temp.lock[1], temp.lock[2], temp.lock[3]);
q.pop();
temp.depth++;
for (int i = 0; i < 3; i++)
{
swap(temp.lock[i], temp.lock[i + 1]);
if (hashit(temp, flag))
{
q.push(temp);
qnum[flag]++;
}
swap(temp.lock[i], temp.lock[i + 1]);
}
for (int i = 0; i < 4; i++)
{
temp.lock[i]++;
if (temp.lock[i] > 9)
temp.lock[i] -= 9;
if (hashit(temp, flag))
{
q.push(temp);
qnum[flag]++;
}
temp.lock[i]--;
if (temp.lock[i] < 1)
temp.lock[i] += 9;
temp.lock[i]--;
if (temp.lock[i] < 1)
temp.lock[i] += 9;
if (hashit(temp, flag))
{
q.push(temp);
qnum[flag]++;
}
temp.lock[i]++;
if (temp.lock[i] > 9)
temp.lock[i] -= 9;
}
}
void work()
{
memset(hash, -1, sizeof(hash));
qnum[2] = 1;
qnum[1] = 1;
queue <Node> q1, q2;
q1.push(s);
q2.push(e);
hashit(s, 1);
hashit(e, 2);
int d1 = 0;
int d2 = 0;
while (!q1.empty() || !q2.empty())
{
if (qnum[1] < qnum[2] && qnum[1] != 0)
{
while (q1.front().depth == d1)
extend(q1, 1);
d1 = q1.front().depth;
}
else
{
while (q2.front().depth == d2)
extend(q2, 2);
d2 = q2.front().depth;
}
if (ans != -1)
return;
}
}
void input()
{
char st1[5], st2[5];
ans = -1;
scanf("%s", st1);
scanf("%s", st2);
if (strcmp(st1, st2) == 0)
{
ans = 0;
return;
}
getin(s.lock, st1);
getin(e.lock, st2);
s.depth = 0;
e.depth = 0;
work();
}
int main()
{
//freopen("D:\\t.txt", "r", stdin);
int t;
scanf("%d", &t);
while (t--)
{
input();
printf("%d\n", ans);
}
return 0;
}