题意:
想法:
先用BFS将箱子向前推,在每次推箱子前有BFS或DFS判断人是否能到达箱子后面;
代码实现:
一 BFS+BFS实现:(时间:0ms)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAX=9;
int n,m,Map[MAX][MAX];
bool Visted[MAX][MAX],Walk[MAX][MAX][MAX][MAX];
int sx1,sy1,spx,spy;
int Move[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct Node
{
int x,y,step;
int px,py;
}Q[MAX*MAX];
struct Stack
{
int x,y;
}S[MAX*MAX];
bool Judge( int x, int y )
{
if( x<=0 || y<=0 || x>m || y>n || Map[x][y]==1 )
return false;
return true;
}
bool BFS( int x, int y, int px, int py, int x1, int y1 )
{
if( x==px && y==py )
return 1;
memset(Visted,0,sizeof(Visted));
Visted[x1][y1]=1;
int front=0,tail=1;
S[0].x=x;
S[0].y=y;
while( front<tail )
{
Stack Now=S[front++];
for( int i=0; i<4; ++i )
{
Stack Next;
Next.x=Now.x+Move[i][0];
Next.y=Now.y+Move[i][1];
if( Judge(Next.x,Next.y) && !Visted[Next.x][Next.y] )
{
Visted[Next.x][Next.y]=1;
S[tail++]=Next;
if( Next.x==px && Next.y==py )
return 1;
}
}
}
return 0;
}
void BFS()
{
Node p1;
p1.x=sx1;
p1.y=sy1;
p1.step=0;
p1.px=spx;
p1.py=spy;
int front=0,tail=1;
Q[0]=p1;
while( front<tail )
{
Node Now=Q[front++];
for( int i=0; i<4; ++i )
{
Node Next;
Next.x=Now.x+Move[i][0];
Next.y=Now.y+Move[i][1];
Next.px=Now.x;
int x=Now.x-Move[i][0];
Next.py=Now.y;
int y=Now.y-Move[i][1];
Next.step=Now.step+1;
if( Judge(Next.x,Next.y) && Judge(x,y) && BFS(Now.px,Now.py,x,y,Now.x,Now.y) )
{
if( Map[Next.x][Next.y]==3 )
{
printf("%d\n",Next.step);
return;
}
if( !Walk[Next.x][Next.y][Next.px][Next.py] )
{
Walk[Next.x][Next.y][Next.px][Next.py]=1;
Q[tail++]=Next;
}
}
}
}
printf("-1\n");
}
int main()
{
//freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while( t-- )
{
scanf("%d%d",&m,&n);
for( int i=1; i<=m; ++i )
{
for( int j=1; j<=n; ++j )
{
scanf("%d",&Map[i][j]);
if( Map[i][j]==2 )
{
sx1=i;
sy1=j;
}
else if( Map[i][j]==4 )
{
spx=i;
spy=j;
// Map[i][j]=0;
}
}
}
memset(Walk,0,sizeof(Walk));
Walk[sx1][sy1][spx][spy]=1;
BFS();
}
return 0;
}
二 BFS+DFS实现 (时间625ms)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAX=8;
int n,m,Map[MAX][MAX];
bool Visted[MAX][MAX],Walk[MAX][MAX][MAX][MAX],flag;
int sx1,sy1,spx,spy;
int Move[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct Node
{
int x,y,step,dir;
int px,py;
}Q[MAX*MAX];
struct Stack
{
int x,y;
}S[MAX*MAX];
void DFS( int x, int y )
{
if( flag )
return;
if( x==spx && y==spy )
{
flag=1;
return;
}
for( int i=0; i<4; ++i )
{
int x1=x+Move[i][0];
int y1=y+Move[i][1];
if( x1<=0 || y1<=0 || x1>m || y1>n || Map[x1][y1]==1 )
continue;
if( !Visted[x1][y1] )
{
Visted[x1][y1]=1;
DFS(x1,y1);
Visted[x1][y1]=0;
}
if( flag )
return;
}
}
void BFS()
{
Node p1;
p1.x=sx1;
p1.y=sy1;
p1.step=0;
p1.dir=-1;
p1.px=spx;
p1.py=spy;
int front=0,tail=0;
Q[tail++]=p1;
while( front<tail )
{
Node Now=Q[front++];
for( int i=0; i<4; ++i )
{
Node Next;
Next.dir=i;
Next.x=Now.x+Move[i][0];
Next.y=Now.y+Move[i][1];
Next.px=Now.x;
int x=Now.x-Move[i][0];
Next.py=Now.y;
int y=Now.y-Move[i][1];
Next.step=Now.step+1;
if( Next.x<=0 || Next.y<=0 || Next.x>m || Next.y>n
|| Map[Next.x][Next.y]==1 )
continue;
if( x<=0 || y<=0 || x>m || y>n
|| Map[x][y]==1 )
continue;
memset(Visted,0,sizeof(Visted));
Visted[Now.x][Now.y]=1;
spx=x;
spy=y;
flag=0;
DFS(Now.px,Now.py);
if( flag )
{
if( !Walk[Next.x][Next.y][Next.px][Next.py] )
{
Q[tail++]=Next;
Walk[Next.x][Next.y][Next.px][Next.py]=1;
}
if( Map[Next.x][Next.y]==3 )
{
printf("%d\n",Next.step);
return;
}
}
}
}
printf("-1\n");
}
int main()
{
//freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while( t-- )
{
scanf("%d%d",&m,&n);
for( int i=1; i<=m; ++i )
{
for( int j=1; j<=n; ++j )
{
scanf("%d",&Map[i][j]);
if( Map[i][j]==2 )
{
sx1=i;
sy1=j;
}
else if( Map[i][j]==4 )
{
spx=i;
spy=j;
}
}
}
memset(Walk,0,sizeof(Walk));
Walk[sx1][sy1][spx][spy]=1;
BFS();
}
return 0;
}