Eight puzzle --HOJ 11918

1、题目类型:模拟、哈希表、BFS。

2、解题思路:(1)模拟Eigh Puzzle的变换方式,并记录在数组中 ;(2)由于变换的最终结果相同,所以采用反向的BFS遍历所有情况,并记录所有情况;(3)在查找情况过程中采用二进制哈希表形式,以便于查找;(4)根据题目每个输入的case对表中进行对应查找,直接输出答案。

3、注意事项:注意哈希表方式,否则TLE。

4、实现方法:(由于又借用模板,所以代码有点乱)

#include<iostream>
#include
<string>
using namespace std;

const int r[] = {0,1,4,3,0,3,4,1,1,2,5,4,1,4,5,2,3,4,7,6,3,6,7,4,4,5,8,7,4,7,8,5};
int final[] = {69074,77576,135289,157120,205759,227590,285303,293805};
int p[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};
int d[362880], q[362880];
int s[9];
int Encode(int* s)
{
int i,j,k,x = 0;
for(i=0;i<9;i++)
{
k
= s[i];
for(j=0;j<i;j++)
if(s[j]<s[i])
k
--;
x
+=k*p[8-i];
}
return x;
}

void Decode(int* s, int x)
{
int i,j;
for(i=0;i<9;i++)
{
s[i]
=x/p[8-i];
x
%=p[8-i];
}
for(i=8;i>=0;i--)
for(j=8;j>i;j--)
if(s[j]>=s[i])
s[j]
++;
}

void Init()
{
int i,x,y,front,rear,ss[9];
memset(d,
-1,sizeof(d));
for(i=0;i<9;i++)
ss[i]
=i;
q[
0]=Encode(ss);
d[q[
0]]=0;
front
=0, rear=1;
while(front<rear)
{
x
= q[front++];
Decode(s,x);
{
for(i=0;i<9;i++)
{
if(s[i]==8)
break;
}
if(i!=0 && i!=1 && i!=2)
{
s[i]
=s[i-3];
s[i
-3]=8;
y
=Encode(s);
if(d[y]<0)
{
d[y]
= d[x] + 1;
q[rear
++] = y;
}
s[i
-3]=s[i];
s[i]
=9;
}
if(i!=2 && i!=5 && i!=8)
{
s[i]
=s[i+1];
s[i
+1]=8;
y
=Encode(s);
if(d[y]<0)
{
d[y]
=d[x]+1;
q[rear
++]=y;
}
s[i
+1]=s[i];
s[i]
=8;
}
if(i!=6 && i!=7 && i!=8)
{
s[i]
=s[i+3];
s[i
+3]=8;
y
=Encode(s);
if(d[y]<0)
{
d[y]
=d[x]+1;
q[rear
++]=y;
}
s[i
+3]=s[i];
s[i]
=8;
}
if(i!=0 && i!=3 && i!=6)
{
s[i]
=s[i-1];
s[i
-1]=8;
y
=Encode(s);
if(d[y]<0)
{
d[y]
=d[x]+1;
q[rear
++]=y;
}
s[i
-1]=s[i];
s[i]
=8;
}
}
}
}

int main()
{
int i,T;
char ch;
Init();
cin
>>T;
while(T--)
{
for(i=0;i<9;i++)
{
cin
>>ch;
if(ch=='#')
s[i]
=8;
else
s[i]
=ch-'1';
}
if(d[Encode(s)]!=-1)
cout
<<d[Encode(s)]<<endl;
else
cout
<<"impossible"<<endl;
}
return 0;
}

 

posted @ 2010-09-27 21:32  勇泽  阅读(402)  评论(0编辑  收藏  举报