跟白书上介绍的8迷问题十分相似,只是这道题需要记录移动的步骤,而且是求最大可移动的步数。
思路:1.保存每一步的状态。2.HASH查找有无重复状态。3.记录最远能达到的状态。主要算法:利用BFS遍历所有状态。
#include<stdio.h>
#include<math.h>
#include<string.h>
#define MAXSTATE 1000003
int origin[3][3],current[3][3],final[3][3];
int maxstep;
char order[100];
int head[MAXSTATE],next[MAXSTATE];
typedef struct que{
int state[3][3];
int step;
char next[100];
}Q;
Q Queue[MAXSTATE+1];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};//L,R,U,D
void Output()
{
int i,j;
for(i=0;i<3;i++)
{
printf("%d",final[i][0]);
for(j=1;j<3;j++)
{
printf(" %d",final[i][j]);
}
printf("\n");
}
printf("%s\n\n",order);
}
int getBlank(int *x,int *y)
{
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if(current[i][j]==0)
{
*x=i;*y=j;
return 1;
}
}
}
return 0;
}
void addOrder(int n,int state)
{
switch(state)
{
case 0:
strcat(Queue[n].next,"L");
break;
case 1:
strcat(Queue[n].next,"R");
break;
case 2:
strcat(Queue[n].next,"U");
break;
case 3:
strcat(Queue[n].next,"D");
break;
}
}
int hash(int n)
{
int i,j,v=0;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
v=v*10+Queue[n].state[i][j];
}
}
return v%MAXSTATE;
}
int isExist(int n)
{
int h,u;
h=hash(n);
u=head[h];
while(u)
{
if(memcmp(Queue[u].state,Queue[n].state,sizeof(Queue[n].state))==0)return 1;
u=next[u];
}
next[n]=head[h];
head[h]=n;
return 0;
}
int BFS()
{
int i,j,k;
int ox,oy,nx,ny,front=0,rear=0;
memcpy(Queue[rear].state,origin,sizeof(origin));
memset(Queue[rear].next,0,sizeof(Queue[rear].next));
memset(head,0,sizeof(head));
Queue[rear++].step=0;
while(front<rear)
{
memcpy(current,Queue[front].state,sizeof(current));//出队
getBlank(&ox,&oy);//获取空格位置
for(i=0;i<4;i++)
{
nx=ox+dx[i];ny=oy+dy[i];//移动空格
if(nx>=0&&nx<3&&ny>=0&&ny<3)//检测是否可移动
{
//移动
current[ox][oy]=current[nx][ny];
current[nx][ny]=0;
//Hash检测状态是否重复
memcpy(Queue[rear].state,current,sizeof(current));
if(!isExist(rear))
{
//入队,记录移动步骤和步数
memcpy(Queue[rear].next,Queue[front].next,sizeof(Queue[front].next));
addOrder(rear,i);
Queue[rear].step=Queue[front].step+1;
if(maxstep<Queue[rear].step)
{
maxstep=Queue[rear].step;
memcpy(order,Queue[rear].next,sizeof(Queue[rear].next));
memcpy(final,Queue[rear].state,sizeof(Queue[rear].state));
}
rear++;
}
//恢复
current[nx][ny]=current[ox][oy];
current[ox][oy]=0;
}
}
front++;
}
}
int main()
{
int cases,puzzle=0;
scanf("%d",&cases);
int i,j,k;
while(cases--)
{
maxstep=0;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&origin[i][j]);
}
}
BFS();
printf("Puzzle #%d\n",++puzzle);
Output();
}
return 0;
}