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 ;
}

 

你可能感兴趣的:(OJ)