POJ 3322 Bloxorz I (bfs)

题意:一款著名的智力游戏:滚木块。输入地图,输出要完成目标最少的步数。

思路:求最少的步数,那么一般就要用BFS,思路很清晰,就是状态保存的时候要注意了,题目数据时500*500的矩阵,木块是3类状态,竖向的、横向的、站立的,因为存储空间的限制,就只能分开保存这三类状态...这类题一定要细心细心在细心.......

  
    
#include < iostream >
#include
< cstdio >
#include
< algorithm >
#include
< memory.h >
#include
< cmath >
#include
< bitset >
#include
< queue >
#include
< vector >
using namespace std;

const int BORDER = ( 1 << 20 ) - 1 ;
const int MAXSIZE = 37 ;
const int MAXN = 1010 ;
const int INF = 0x4ffffff ;

#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))

#define SET_NODE(no,a,b,c,d) {no.state=a,no.x=b,no.y=c,no.val=d;}

int n,m,ex,ey;
int ans;
bool visit[ 3 ][MAXN][MAXN]; // 0:oo 1:horizon 2:vertical
char g[MAXN][MAXN];

int dir[ 5 ][ 4 ][ 3 ] = {
{{
0 , 0 , 0 },{ 0 , 0 , 0 },{ 0 , 0 , 0 },{ 0 , 0 , 0 }},
{{
- 2 , 0 , 4 },{ 1 , 0 , 4 },{ 0 , - 2 , 2 },{ 0 , 1 , 2 }},
{{
- 1 , 0 , 2 },{ 1 , 0 , 2 },{ 0 , - 1 , 1 },{ 0 , 2 , 1 }},
{{
0 , 0 , 0 },{ 0 , 0 , 0 },{ 0 , 0 , 0 },{ 0 , 0 , 0 }},
{{
- 1 , 0 , 1 },{ 2 , 0 , 1 },{ 0 , - 1 , 4 },{ 0 , 1 , 4 }}};

typedef
struct {
int state;
int x,y;
int val;
}NODE;
NODE start_node;

int init()
{
CLR(visit,
0 );
CLR(g,
0 );
ans
= 0 ;
return 0 ;
}
int input()
{
int i,j,tmp,k;
int pos[ 2 ][ 2 ];
int tag = 0 ;
for (i = 0 ; i < n; ++ i)
scanf(
" %s " ,g[i]);
for (i = 0 ; i < n; ++ i)
for (j = 0 ; j < m; ++ j)
{
if (g[i][j] != ' # ' )
{
if (g[i][j] == ' X ' )
{
pos[tag][
0 ] = i;
pos[tag][
1 ] = j;
++ tag;
}
else if (g[i][j] == ' O ' )
{
g[i][j]
= ' . ' ;
ex
= i;
ey
= j;
}
}
}
if (tag == 1 )
{
SET_NODE(start_node,
1 ,pos[ 0 ][ 0 ],pos[ 0 ][ 1 ], 0 );
visit[
0 ][start_node.x][start_node.y] = true ;
return 0 ;
}
if (pos[ 0 ][ 0 ] == pos[ 1 ][ 0 ])
{
tmp
= MIN(pos[ 0 ][ 1 ],pos[ 1 ][ 1 ]);
SET_NODE(start_node,
2 ,pos[ 0 ][ 0 ],tmp, 0 );
visit[
1 ][start_node.x][start_node.y] = true ;
return 0 ;
}
if (pos[ 0 ][ 1 ] == pos[ 1 ][ 1 ])
{
tmp
= MIN(pos[ 0 ][ 0 ], pos[ 1 ][ 0 ]);
SET_NODE(start_node,
4 ,tmp,pos[ 0 ][ 1 ], 0 );
visit[
2 ][start_node.x][start_node.y] = true ;
}
return 0 ;
}
bool _in( const int & x, const int & y)
{
if (x < 0 || x >= n || y < 0 || y >= m)
return false ;
return true ;
}
bool _check( const NODE & node)
{
int x,y,a,b;
if (node.x < 0 || node.y < 0 )
return false ;
if (node.state & 1 )
{
if ( ! visit[ 0 ][node.x][node.y] && g[node.x][node.y] == ' . ' )
{
visit[
0 ][node.x][node.y] = true ;
return true ;
}
else
return false ;
}
if (node.state & 2 )
{
x
= a = node.x;
y
= node.y;
b
= y + 1 ;
if (visit[ 1 ][x][y])
return false ;
if (g[x][y] == ' # ' || g[a][b] == ' # ' )
return false ;
visit[
1 ][x][y] = true ;
}
else
{
x
= node.x;
y
= b = node.y;
a
= x + 1 ;
if (visit[ 2 ][x][y])
return false ;
if (g[x][y] == ' # ' || g[a][b] == ' # ' )
return false ;
visit[
2 ][x][y] = true ;
}
return true ;
}
int bfs()
{
int a,b,x,y,i,j,tmp;

NODE t_node,node;
queue
< NODE > que;
while ( ! que.empty())
que.pop();
que.push(start_node);
while ( ! que.empty())
{
node
= que.front();
que.pop();

if ((node.state & 1 ) && node.x == ex && node.y == ey)
return node.val;
for ( int i = 0 ; i < 4 ; ++ i)
{
x
= node.x + dir[node.state][i][ 0 ];
y
= node.y + dir[node.state][i][ 1 ];
SET_NODE(t_node,dir[node.state][i][
2 ],x,y,node.val + 1 );
if (_check(t_node))
que.push(t_node);
}
}
return - 1 ;
}
int work()
{
ans
= bfs();
if (ans == - 1 )
printf(
" Impossible\n " );
else
printf(
" %d\n " ,ans);
return 0 ;
}
int main()
{
while (scanf( " %d%d " , & n, & m) != EOF)
{
if ( ! n && ! m)
break ;
init();
input();
work();
}
return 0 ;
}

 

你可能感兴趣的:(poj)