POJ_1077

经典的八数码问题,做完之后突然想到一句台词:“我的人生又趋于完整了一点……”。

一开始接触这个确实觉得比较难,后来突然在刘汝佳书上发现原来是有讲这个问题的,于是我如获至宝,赶紧研究起刘汝佳的代码来,边学边写,总算是把代码写完了,同时又在他的代码和提示的基础上自己写了打印路径的方式。

研究这个题的代码时,第一次比较认真地看了Hash的有关内容,掌握了一些基础的Hash判重的方法,同时对状态的表示也有了更深一步的理解,总之收获不菲呀。

#include<stdio.h>
#include
<string.h>
#define MAX 1000000
#define HASH 1000003
const int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
int dis[MAX],goal[9],st[MAX][9],fa[MAX],move[MAX];
int head[HASH],next[MAX];
char path[500000];
void lookup()
{
memset(head,
0,sizeof(head));
}
int hash(int s)
{
int v=0,i;
for(i=0;i<9;i++)
v
=v*10+st[s][i];
return v%HASH;
}
int insert(int s)
{
int h,u;
h
=hash(s);
for(u=head[h];u!=0;u=next[u])
if(memcmp(st[u],st[s],sizeof(st[s]))==0)
return 0;
next[s]
=head[h];
head[h]
=s;
return 1;
}
int bfs()
{
int x,y,z,d,newx,newy,newz,front,rear;
lookup();
front
=1;
rear
=2;
dis[
1]=fa[1]=0;
while(front<rear)
{
if(memcmp(st[front],goal,sizeof(goal))==0)
return front;
for(z=0;z<9;z++)
if(st[front][z]==0)
break;
x
=z/3;
y
=z%3;
for(d=0;d<4;d++)
{
newx
=x+dx[d];
newy
=y+dy[d];
newz
=newx*3+newy;
if(newx>=0&&newx<3&&newy>=0&&newy<3)
{
memcpy(st[rear],st[front],
sizeof(st[front]));
st[rear][newz]
=st[front][z];
st[rear][z]
=st[front][newz];
if(insert(rear))
{
dis[rear]
=dis[front]+1;
move[rear]
=d;
fa[rear]
=front;
rear
++;
}
}
}
front
++;
}
return 0;
}
int main()
{
int i,j,ans;
char b[5];
for(i=0;i<9;i++)
{
scanf(
"%s",b);
if(b[0]=='x')
st[
1][i]=0;
else
st[
1][i]=b[0]-'0';
}
for(i=0;i<9;i++)
goal[i]
=(i+1)%9;
ans
=bfs();
if(ans==0)
printf(
"unsolvable\n");
else
{
i
=dis[ans];
path[i]
='\0';
j
=ans;
for(i-=1;j!=0;i--,j=fa[j])
switch(move[j])
{
case 0: path[i]='u';break;
case 1: path[i]='d';break;
case 2: path[i]='l';break;
case 3: path[i]='r';break;
}
printf(
"%s\n",path);
}
return 0;
}

  

posted on 2011-08-17 00:22  Staginner  阅读(704)  评论(1编辑  收藏  举报