看注释吧
#include<stdio.h>
#include<iostream>
#include<queue>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
typedef struct loc
{
int x,y;
}loc;
typedef struct map//图
{
loc pos[48],gap[4];//各个值的坐标,空白处的坐标
string s;//序列顺序
int dis;//移动数
}map;
char gra[4][8];//初始数组
string c2s()
{
string s="";
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)
s+=gra[i][j];
return s;
}
int hash1(string s)//给每一种图对应一个关键值,防重。
{
long long h=0;
for(int i=0;i<32;i++)
{
h=(h<<1)+s[i];
}
return h%999991;
}
int vis[1000000];
string End="";
char ss[32]={11,12,13,14,15,16,17,0,21,22,23,24,25,26,27,0,31,32,33,34,35,36,37,0,41,42,43,44,45,46,47,0};
int Bfs()
{
queue<map> q;
loc temp,temp1;
map now,then;
int k=0,a,b;
while(!q.empty())q.pop();
string s1;
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)//初始化
{
temp.x=i;temp.y=j;
if(gra[i][j]==0)now.gap[k++]=temp;
else now.pos[gra[i][j]]=temp;
}
memset(vis,0,sizeof(vis));
s1=c2s();now.s=s1;vis[hash1(now.s)]=1;
now.dis=1;
q.push(now);
int e;e=hash1(End);
while(!q.empty()&&!vis[e])
{
now=q.front();q.pop();
then=now;then.dis=now.dis+1;
for(int i=0;i<4;i++)//四种改变的可能
{
temp=then.gap[i];
a=8*temp.x+temp.y-1;
if(then.s[a]%10==7||then.s[a]==0)continue;//尾数为7和为空白处不可进行移动操作,直接跳过。
temp1=then.pos[then.s[a]+1];
b=temp1.x*8+temp1.y;
swap(then.s[a+1],then.s[b]);//改变序列
k=hash1(then.s);
if(!vis[k])
{
if(k==e)return then.dis-1;
then.gap[i]=temp1;
then.pos[then.s[a+1]]=temp;
q.push(then);
vis[k]=1;
then.gap[i]=temp;
then.pos[then.s[a+1]]=temp1;
}
swap(then.s[a+1],then.s[b]);//恢复原来状态
}
}
return vis[e]-1;
}
int main()
{
int i,a;
for(i=0;i<32;i++)End+=ss[i];
int t;
scanf("%d",&t);
while(t--)
{
memset(gra,0,sizeof(gra));
for(int j=0;j<4;j++)
for(int k=1;k<8;k++)
{
scanf("%d",&a);
gra[j][k]=(char)a;
if(a%10==1) swap(gra[j][k],gra[(a/10)-1][0]); //把11,21,31,41挑出放在最左边
}
printf("%d\n",Bfs());
//if(t>0)printf("\n");
}
return 0;
}