zoukankan      html  css  js  c++  java
  • hdu 1254 需注意的地方 果枫

    题意:如题所说。

    注意:1.要考虑人是否能走到推箱子的地方
            2.箱子经过的格子可以再次经过,而箱子经过同一个格子从同一个方向来的只能有一次
            3.人不能穿过箱子

    解法:BFS+BFS

    AC代码:

    View Code
    //bfs+bfs
    #include<iostream>
    #include<queue>
    using namespace std;
    
    #define mem(x,y) memset(x,y,sizeof(x));//牛b的数组初始化,网上学的
    const int M=25;
    int useb[M][M][4],used[M][M];//用作标记useb[][][]之所以是三维数组是因为不单单要标记这一点而是要标记在这点上的方向
    int map[M][M];//地图
    int n,m;//输入地图的行和列
    int bx,by,gx,gy,px,py;// bx,by箱子的坐标  gx,gy目的地的坐标  px,py人的坐标
    int nn[4][2]={{0,1},{-1,0},{0,-1},{1,0}};//方向向量:左,上,右,下
    int foat;//深搜时用作判断是否能找到该点
    
    struct node//节点
    {
        int bx,by;
        int px,py;
        int step;
    
        node(int x,int y,int a,int b,int s)//初始化节点
        {
            bx=x,by=y,px=a,py=b,step=s;
        }
    
        const bool operator <(const node &d)//主要作用是用于队列中的元素按step的升序排列
        {
            return step>d.step;
        }
    };
    
    
    bool outside(int x,int y)//判断是否出界
    {
        if(x>0&&x<=n&&y>0&&y<=m&&map[x][y]!=1)
            return 0;
        else 
            return 1;
    }
    
    
    
    //void dfs(int sx,int sy,int ex,int ey)//悲剧用深搜超时了
    //{
    // if(sx==ex&&sy==ey)
    // {
    //  foat=1;
    //  return ;
    // }
    // for(int i=0;i<4;i++)
    // {
    //  int x=sx+nn[i][0];
    //  int y=sy+nn[i][1];
    //  if(map[x][y]==1||used[x][y]==1||outside(x,y))
    //   continue;
    //  else
    //  {
    //   used[x][y]=1;
    //   dfs(x,y,ex,ey);
    //   used[x][y]=0;
    //  }
    // }
    //}
    
    
    int dfs ( int sx, int sy, int ex, int ey ) //搜索人能否从一点移动到另一点
    {  
        if ( sx == ex && sy == ey ) 
            return 1;
        queue < int > q;
        /*int hh[11][11]; */
        mem(used,0);
        //hh[sx][sy] = 1;
        used[sx][sy]=1;
        q.push ( sx ), q.push ( sy );
        while ( q.size () ) 
        {
            int x = q.front (); 
            q.pop ();
            int y = q.front (); 
            q.pop ();
            for ( int i = 0; i < 4; ++ i ) 
            {
                int xx = x+nn[i][0], yy = y+nn[i][1];
                if ( outside ( xx, yy ) ) 
                    continue;
                if ( !used[xx][yy] ) 
                {
                    if ( xx == ex && yy == ey ) 
                        return 1;
                    q.push ( xx ); 
                    q.push ( yy );
                    used[xx][yy] = 1;
                }
            }
        }
        return 0;
    }
    
    
    
    
    int bfs()
    {
        queue<node>q;
        q.push(node(bx,by,px,py,0));
        while(!q.empty())
        {
            node temp=q.front();
            q.pop();
            if(temp.bx==gx&&temp.by==gy)
                return temp.step;
            for(int i=0;i<4;i++)//i<4是因为有四个方向,每一个方向都要判断是否能进队列
            {
                bx=temp.bx+nn[i][0];
                by=temp.by+nn[i][1];
                px=temp.bx-nn[i][0];
                py=temp.by-nn[i][1];
    
                if(outside(bx,by)||outside(px,py)||useb[bx][by][i])//判断是否出界,或在这个方向上走过
                    continue;
    
                map[temp.bx][temp.by]=1;//防止人穿过箱子当前所在的位置
    
                mem(used,0);
                /*foat=0;*/
                if(!dfs(temp.px,temp.py,px,py))//判断人是否能从原来的点移动到所需的点
                {
                    map[temp.bx][temp.by]=0;//即使不能到达,也必须还原标记
                    continue;
                }
                map[temp.bx][temp.by]=0;//能到达还原标记
    
                if(bx==gx&&by==gy)//找到
                    return  temp.step+1;
    
                q.push(node(bx,by,temp.bx,temp.by,temp.step+1));
                useb[bx][by][i]=1;
            }
        }
        return -1;
    }
    
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            map[1][1]=1;
            mem(useb,0);
            mem(map,0);
            int i,j;
            cin>>n>>m;
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=m;j++)
                {
                    cin>>map[i][j];
                    switch(map[i][j])
                    {
                    case 2:bx=i,by=j;break;
                    case 3:gx=i,gy=j;break;
                    case 4:px=i,py=j;break;
                    }
                }
            }
            cout<<bfs()<<endl;
        }
        return 0;
    }
    /*
    
    5 6
    0 0 0 0 0 3
    1 0 1 4 0 1
    0 0 1 0 0 1
    1 0 2 0 0 1
    0 0 0 0 0 1
    
    5 5
    0 3 0 0 0
    1 0 1 4 0
    0 0 1 0 0
    1 0 2 0 0
    0 0 0 0 0
    */

     


     

  • 相关阅读:
    Educational Codeforces Round 67 D. Subarray Sorting
    2019 Multi-University Training Contest 5
    Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code
    Educational Codeforces Round 69 D. Yet Another Subarray Problem
    2019牛客暑期多校训练第六场
    Educational Codeforces Round 68 E. Count The Rectangles
    2019牛客多校第五场题解
    2019 Multi-University Training Contest 3
    2019 Multi-University Training Contest 2
    [模板] 三维偏序
  • 原文地址:https://www.cnblogs.com/zgfailmr/p/2672029.html
Copyright © 2011-2022 走看看