uva10422(Knights in FEN)-bfs+哈希(隐式图搜索)

来源:互联网 发布:algorithm基础算法 编辑:程序博客网 时间:2024/06/16 05:28

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1363

#include<stdio.h>#include<string.h>#define MAX 5000000int 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");elseprintf("Solvable in %d move(s).\n",te);}return 0;}


0 0