hoj1195

双向广度优先搜索,本来是想哪个节点少扩展哪个,但是有一个问题,就是有可能上端的x层节点扩展出x+1层,下端的y层扩展出y+1层,这两个+1层有重合,便直接跳出,输出x+y+1,这样可能导致错误,因为x层节点并没有完全扩展完毕,很可能接下来要扩展的x层节点会扩展出的x+1层节点直接与y层节点重合。

View Code
#include <iostream>
#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;
}
posted @ 2011-03-29 10:33  金海峰  阅读(202)  评论(0编辑  收藏  举报