hdu 1254 推箱子(BFS+BFS或BFS+DFS)

题意:

想法:

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


 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值