将4*8的矩阵转成一个64位整数,我是用乘2的方法转成long long的,判断有没有出现过这个状态就用有没有出现这个数字来表示,然后用哈希链地址发解决冲突,x%mod相同的放在一个链表里面,剩下的就是普通的广搜了。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef __int64 LL;
const int mod = 1000007;
LL hah[mod], first[mod], tnext[mod], cnt;
struct node
{
int a[4][8];
int x[4];
int y[4];
int dis;
}s, e;
LL res;
LL getHash(int a[][8])
{
LL ans = 0;
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 8; j++)
{
ans = (ans<<(LL)1)+(LL)a[i][j];
}
}
return ans;
}
bool inser(int a[][8])
{
LL tmp = getHash(a);
for(int i = first[tmp%mod]; i != -1; i = tnext[i])
{
if(hah[i] == tmp)
return false;
}
hah[cnt] = tmp;
tnext[cnt] = first[tmp%mod];
first[tmp%mod] = cnt++;
return true;
}
bool ok(int a[][8])
{
/*for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 8; j++)
{
if(s.a[i][j] != a[i][j])
return false;
}
}
return true;*/
LL tmp = getHash(a);
if(tmp == res)
return true;
return false;
}
int BFS()
{
queue<node> Q;
Q.push(e);
res = getHash(s.a);
while(!Q.empty())
{
node u = Q.front();
Q.pop();
for(int i = 0; i < 4; i++)
{
node t;
for(int j = 0; j < 4; j++)
{
t.x[j] = u.x[j];
t.y[j] = u.y[j];
for(int k = 0; k < 8; k++)
{
t.a[j][k] = u.a[j][k];
}
}
if(ok(u.a))
{
return u.dis;
}
int x = u.x[i];
int y = u.y[i];
if(y <= 0 || u.a[x][y-1] == 0 || u.a[x][y-1]%10 == 7)
continue;
int num = u.a[x][y-1]+1;
int flag = 0;
for(int j = 0; j < 4 && !flag; j++)
{
for(int k = 0; k < 8 && !flag; k++)
{
if(t.a[j][k] == num)
{
flag = 1;
t.a[j][k] = 0;
t.a[x][y] = num;
t.x[i] = j;
t.y[i] = k;
t.dis = u.dis+1;
if(inser(t.a))
{
Q.push(t);
}
}
}
}
}
}
return -1;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
s.a[0][0] = s.a[1][0] = s.a[2][0] = s.a[3][0] = 0;
for(int i = 0; i < 4; i++)
{
s.a[i][7] = 0;
for(int j = 0; j < 7; j++)
{
s.a[i][j] = (i+1)*10+j+1;
}
}
memset(hah, -1, sizeof(hah));
memset(first, -1, sizeof(first));
cnt = 0;
int k = 0;
memset(e.a, 0, sizeof(e.a));
e.dis = 0;
for(int i = 0; i < 4; i++)
{
for(int j = 1; j <= 7; j++)
{
scanf("%d", &e.a[i][j]);
if(e.a[i][j] == 11)
{
swap(e.a[0][0], e.a[i][j]);
e.x[k] = i;
e.y[k++] = j;
}
if(e.a[i][j] == 21)
{
swap(e.a[1][0], e.a[i][j]);
e.x[k] = i;
e.y[k++] = j;
}
if(e.a[i][j] == 31)
{
swap(e.a[2][0], e.a[i][j]);
e.x[k] = i;
e.y[k++] = j;
}
if(e.a[i][j] == 41)
{
swap(e.a[3][0], e.a[i][j]);
e.x[k] = i;
e.y[k++] = j;
}
}
}
int ans = BFS();
printf("%d\n", ans);
}
return 0;
}