基本按照刘汝佳书的例题去解.WA了一次:step[front] >10 而不是 step[front]>=10,因为 走10步 可能有多种状态,不应马上return -1;
#include<stdio.h>
#include<string.h>
const int maxstate=2000000;
typedef int State[25];
State que[maxstate];
int step[maxstate];
State goal={1,1,1,1,1,0,1,1,1,1,0,0,2,1,1,0,0,0,0,1,0,0,0,0,0};
State init;
const int dx[]={1,2,2,1,-1,-2,-2,-1};
const int dy[]={2,1,-1,-2,2,1,-1,-2};
const int maxhash=1000003;
int head[maxhash];
int next[maxstate];
int hash(State& s)
{
int v=0;
for(int i=0;i < 25;i++)
{
v=v*2+s[i];
}
return v%maxhash;
}
bool tryinsert(int queid)
{
int h=hash(que[queid]);
int fir=head[h];
while(fir)
{
if(0==memcmp(que[queid],que[fir],sizeof(que[queid])))
return false;
fir = next[fir];
}
next[queid]=head[h];
head[h]=queid;
return true;
}
int bfs()
{
//
memset(head,0,sizeof(head));
int front=0,rear=0;
memcpy(que[rear],init,sizeof(State));
step[rear++]=0;
while(front<rear)
{
State& s = que[front];
if(memcmp(&s,&goal,sizeof(s))==0)
return step[front];
if(step[front] >10) //> 不是>=
return -1;
int z;
for(z=0; z<25;z++)
if(s[z]==2)
break;
int x,y;
x = z/5;
y = z%5;
int nx,ny,nz;
for(int i=0; i<8;i++)
{
nx=x+dx[i];
ny=y+dy[i];
nz=nx*5+ny;
if(nx>=0&&ny>=0&&nx<5&&ny<5)
{
State& t =que[rear];
memcpy(&t,&s,sizeof(s));
t[nz]=s[z];
t[z]=s[nz];
step[rear]=step[front]+1;
if(tryinsert(rear))
rear++;
}
}
front++;
}
}
int main()
{
//
freopen("input.txt","r",stdin);
//freopen("out.txt","w",stdout);
int numg;
scanf("%d",&numg);
while(getchar()!='\n')
continue;
char ch;
while(numg--)
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
ch=getchar();
if(ch==' ')
{
init[i*5+j]=2;
}
else init[i*5+j]=ch-'0';
}
while(getchar()!='\n')
continue;
}
int res=bfs();
if(res==-1)
puts("Unsolvable in less than 11 move(s).");
else
printf("Solvable in %d move(s).\n",res);
}
}