UVA 10085 The most distant state

UVA_10085

这个题目和八数码问题基本是一样的,只不过八数码问题是求变成指定图形所需的最少步骤,而这个问题是从指定图形出发,去找一个图形使得其按少步骤操作以得到指定图形所需的步骤是所有图形中最多的。

从代码的角度讲,八数码问题的广搜的while循环是在遇到指定图形时退出的,而这个问题的while循环只能是在front=rear时退出,这样才算搜完了所有情况。

对于八数码问题的相关知识可以参考刘汝佳白书的P132

#include<stdio.h>
#include
<string.h>
#define HASH 100003
int st[1000000][9],fa[1000000],move[1000000];
int head[1000003],next[1000000];
int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
int hash(int *p)
{
int i,v;
v
=0;
for(i=0;i<9;i++)
v
=v*10+p[i];
return v%HASH;
}
int insert(int k)
{
int i,h;
h
=hash(st[k]);
for(i=head[h];i!=-1;i=next[i])
if(memcmp(st[i],st[k],sizeof(st[k]))==0)
break;
if(i==-1)
{
next[k]
=head[h];
head[h]
=k;
return 1;
}
else
return 0;
}
void printpath(int k)
{
if(fa[k]==-1)
return;
printpath(fa[k]);
if(move[k]==0)
printf(
"U");
else if(move[k]==1)
printf(
"D");
else if(move[k]==2)
printf(
"L");
else
printf(
"R");
}
int main()
{
int i,j,k,temp,t,tt;
int front,rear,x,y,z,newx,newy,newz;
scanf(
"%d",&t);
for(tt=0;tt<t;tt++)
{
front
=rear=0;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
scanf(
"%d",&st[rear][i*3+j]);
fa[rear]
=move[rear]=-1;
memset(head,
-1,sizeof(head));
insert(rear);
rear
++;
while(front<rear)
{
for(z=0;z<9;z++)
if(st[front][z]==0)
break;
x
=z/3;
y
=z%3;
for(i=0;i<4;i++)
{
memcpy(st[rear],st[front],
sizeof(st[front]));
newx
=x+dx[i];
newy
=y+dy[i];
if(newx>=0&&newx<3&&newy>=0&&newy<3)
{
newz
=newx*3+newy;
temp
=st[rear][z];
st[rear][z]
=st[rear][newz];
st[rear][newz]
=temp;
if(insert(rear))
{
fa[rear]
=front;
move[rear]
=i;
rear
++;
}
}
}
front
++;
}
printf(
"Puzzle #%d\n",tt+1);
for(i=0;i<9;i++)
{
if(i%3!=0)
printf(
" ");
printf(
"%d",st[rear-1][i]);
if((i+1)%3==0)
printf(
"\n");
}
printpath(rear
-1);
printf(
"\n\n");
}
return 0;
}

  

你可能感兴趣的:(ant)