题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1363
#include<stdio.h>
#include<string.h>
#define MAX 5000000
int dx[8]={1,2,2,1,-1,-2,-2,-1},dy[8]={-2,-1,1,2,2,1,-1,-2};
int st[MAX][25];
int temp[25],aim[25]={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},head[MAX],next[MAX],dist[MAX];
/*哈希函数*/
int has(int s){
int i,ha=0;
for(i=0;i<25;i++) ha=2*ha+st[s][i];
return ha%MAX;
}
/*判断是否可以插入*/
int try_to_inser(int s){
int h=has(s);
int u=head[h];//得到头结点的位置
while(u){//若是其为0则说明这个位置没有存放结点,若是不为0则继续寻找下一个结点是否存在有被访问过的结点
if(memcmp(st[u],st[s],sizeof(st[s]))==0) return 0;
u=next[u];
}
next[s]=head[h];//将头结点移到s的下一个结点的位置
head[h]=s;//头结点存储s,完成插入
return 1;
}
void init_look_uptabl(){
memset(head,0,sizeof(head));
memset(next,0,sizeof(next));
}
int dfs(){
init_look_uptabl();
int fron=0,rear=1;
dist[1]=0;
while(fron<rear){
fron++;
if(dist[fron]>10) return -1;//若是操作次数大于10,则说明不能在10步以内到达目标状态
else if(memcmp(st[fron],aim,sizeof(aim))==0) return dist[fron];//到达目标状态,返回操作步骤
else{
int i;
for(i=0;i<25;i++) if(st[fron][i]==2) break;
int x,y,mark=i;
y=i/5,x=i%5;
for(i=0;i<8;i++){
int ty=y+dy[i],tx=x+dx[i];
if(ty>=0&&ty<5&&tx>=0&&tx<5){
rear++;
int tc[25];
memcpy(&tc,&st[fron],sizeof(tc));
tc[mark]=st[fron][ty*5+tx],tc[ty*5+tx]=2;
memcpy(&st[rear],&tc,sizeof(tc));
dist[rear]=dist[fron]+1;//操作步数等于上一次的步数+1;
if(try_to_inser(rear)==0) rear--;
}
}
}
}
return -1;
}
int main(){
int t;
scanf("%d",&t);
char s[5];
getchar();
while(t--){
int i,j;
for(i=0;i<5;i++){
gets(s);
for(j=0;j<5;j++){
if(s[j]==' ') st[1][i*5+j]=2;
else st[1][i*5+j]=s[j]-'0';
}
}
int te=dfs();
if(te==-1)
printf("Unsolvable in less than 11 move(s).\n");
else
printf("Solvable in %d move(s).\n",te);
}
return 0;
}