Holedox Moving--POJ 1324

1、题目类型:模拟、贪吃蛇游戏、哈希表、BFS。

2、解题思路:题意,给出活动空间大小、蛇身位置、空间中障碍物位置、目标位置,求解蛇的最少移动步数。难点,用进制的哈希对蛇身相对位置的保存。步骤,(1)根据输入记录Holedox的位置和stones的位置;(2)对Holedox的位置进行哈希状态压缩,哈希加密方式为Staten=Holedox位置的逐一相对位置的4进制*总行数*总列数+总行数*行位置+列位置(解密方式类似);(3)BFS搜索目标情况,成功解密Holedox‘s head位置为(0,0)返回此时step,否则返回-1。

3、注意事项:哈希的构造方法必须唯一,且在int的控制范围以内否则TLE;BFS中常用变量尽量用全局变量,避免Runtime Error。

4、实现方法:

  
    
#pragma warning(disable:4786)
#include
< iostream >
#include
< queue >
#include
< map >
using namespace std;

struct Node
{
int state;
int step;
};

Node Q[
1000000 ];
int X[ 4 ] = { 0 , 1 , 0 , - 1 };
int Y[ 4 ] = { 1 , 0 , - 1 , 0 };
int R,C,L,state;
int sn[ 9 ][ 2 ],mat[ 30 ][ 30 ];
bool vis[ 6800000 ];
map
< int , int > S;

void Init()
{
int i,n,a,b;
for (i = 0 ;i < L;i ++ )
{
scanf(
" %d%d " , & sn[i][ 0 ], & sn[i][ 1 ]);
sn[i][
0 ] -- ;
sn[i][
1 ] -- ;
}
cin
>> n;
memset(mat,
0 , sizeof (mat));
for (i = 0 ;i < n;i ++ )
{
scanf(
" %d%d " , & a, & b);
a
-- ;
b
-- ;
mat[a][b]
= 1 ;
}
S.clear();
}

// 获得Holedox相对位置
int GetDir( int now[ 2 ], int pre[ 2 ])
{
if (now[ 1 ] == pre[ 1 ] + 1 )
return 0 ;
if (now[ 1 ] == pre[ 1 ] - 1 )
return 2 ;
if (now[ 0 ] == pre[ 0 ] + 1 )
return 1 ;
if (now[ 0 ] == pre[ 0 ] - 1 )
return 3 ;
return 0 ;
}

bool Judge( int ssn[][ 2 ], int sn[][ 2 ])
{
int i;
if ( ! (ssn[ 0 ][ 0 ] >= 0 && ssn[ 0 ][ 0 ] < R && ssn[ 0 ][ 1 ] >= 0 && ssn[ 0 ][ 1 ] < C && mat[ssn[ 0 ][ 0 ]][ssn[ 0 ][ 1 ]] == 0 ))
return false ;
for (i = 0 ;i < L;i ++ )
{
if (ssn[ 0 ][ 0 ] == sn[i][ 0 ] && ssn[ 0 ][ 1 ] == sn[i][ 1 ])
return false ;
}
return true ;
}

int BFS()
{
int i,j,k,front = 0 ,rear = 0 ;
int head[ 2 ],tsn[ 9 ][ 2 ];
Node tmp;
memset(vis,
0 , sizeof (vis));
tmp.state
= state;
tmp.step
= 0 ;
Q[rear
++ ] = tmp;
vis[state]
= 1 ;
while (front < rear)
{
tmp
= Q[front];
front
= (front + 1 ) % 1000000 ;
head[
1 ] = tmp.state % (C * R) % C;
head[
0 ] = tmp.state % (C * R) / C;
state
= tmp.state / (C * R);
sn[
0 ][ 0 ] = head[ 0 ];
sn[
0 ][ 1 ] = head[ 1 ];
for (i = 1 ;i < L;i ++ )
{
sn[i][
0 ] = sn[i - 1 ][ 0 ] + X[state % 4 ];
sn[i][
1 ] = sn[i - 1 ][ 1 ] + Y[state % 4 ];
state
/= 4 ;
}
if (head[ 0 ] == 0 && head[ 1 ] == 0 )
return tmp.step;
for (i = 0 ;i < 4 ;i ++ )
{
tsn[
0 ][ 0 ] = sn[ 0 ][ 0 ] + X[i];
tsn[
0 ][ 1 ] = sn[ 0 ][ 1 ] + Y[i];
if (Judge(tsn,sn))
{
state
= 0 ;
int s = 1 ;
for (j = 1 ;j < L;j ++ )
{
tsn[j][
0 ] = sn[j - 1 ][ 0 ];
tsn[j][
1 ] = sn[j - 1 ][ 1 ];
}
for (k = 1 ;k < L;k ++ )
{
state
= state + GetDir(tsn[k],tsn[k - 1 ]) * s;
s
*= 4 ;
}
state
= state * R * C + tsn[ 0 ][ 0 ] * C + tsn[ 0 ][ 1 ];
if ( ! vis[state])
{
Node N;
N.state
= state;
N.step
= tmp.step + 1 ;
vis[state]
= 1 ;
Q[rear]
= N;
rear
= (rear + 1 ) % 1000000 ;
}
}
}
}
return - 1 ;
}

void Solve( int ca)
{
int i,s = 1 ;
state
= 0 ;
for (i = 1 ;i < L;i ++ )
{
state
= state + GetDir(sn[i],sn[i - 1 ]) * s;
s
*= 4 ;
}
state
= state * R * C + sn[ 0 ][ 0 ] * C + sn[ 0 ][ 1 ];
cout
<< " Case " << ca ++<< " : " ;
cout
<< BFS() << endl;
}

int main()
{
int ca = 1 ;
while (scanf( " %d%d%d " , & R, & C, & L))
{
if (R == 0 && C == 0 && L == 0 )
break ;
Init();
Solve(ca
++ );
}
return 0 ;
}

 

你可能感兴趣的:(poj)