代码:(bfs模板)立体推箱子

Posted tztqwq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码:(bfs模板)立体推箱子相关的知识,希望对你有一定的参考价值。

这类题叫做图的广度优先遍历题,不过给你的是隐式图罢了(细节多)。

考点就是隐式图的遍历(难度主要集中在判断某节点是否与当前节点联通这块)。

#include<bits/stdc++.h>
using namespace std;
const int maxn=501;
char a[maxn][maxn];
int n,m;

int dx[4]=1,-1,0,0;
int dy[4]=0,0,1,-1;

struct nodeint r,c,lie;st,ed;//0: lizhe 1:shu tang 2:heng tang

bool valid(int r,int c) 
    return r>=1&&r<=n&&c>=1&&c<=m;


bool valid(node v)

    bool jd= a[v.r][v.c]!='#' && v.r>=1 && v.r<=n && v.c>=1 && v.c<=m;
    if(v.lie==0)
    
        return a[v.r][v.c]!='E'&&jd;
    
    if(v.lie==1)
    
        return jd&&a[v.r+1][v.c]!='#' && v.r+1>=1 && v.r+1<=n && v.c>=1 && v.c<=m;
    
    if(v.lie==2)
    
        return jd&&a[v.r][v.c+1]!='#' && v.r>=1 && v.r<=n && v.c+1>=1 && v.c+1<=m;
    


void findsted()

    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    
        if(a[i][j]=='O') 
            ed.r=i,ed.c=j,ed.lie=0;
            a[i][j]='.';
        
    
    int flag=0;
    for(int i=1;i<=n;++i) 
        if(flag) break;
        for(int j=1;j<=m;++j)
        
            if(a[i][j]=='X') 
                st.r=i,st.c=j;
                for(int k=0;k<4;++k) 
                    int x=i+dx[k],y=j+dy[k];
                    if(valid(x,y)&&a[x][y]=='X') 
                        a[i][j]=a[x][y]='.';
                        if(k==0) 
                            st.lie=1;
                        
                        if(k==2) 
                            st.lie=2;
                        
                        flag=1;
                        break;
                    
                
            
            if(a[i][j]=='X')
            
                st.lie=0;
                a[i][j]='.';
                flag=1;break;
            
            
        
    
    
    


int r_move[3][4]=-2,1,0,0,-1,2,0,0,0,0,1,-1;
int c_move[3][4]=0,0,-2,1,0,0,-1,1,-1,2,0,0;
int lie_move[3][4]=1,1,2,2,0,0,1,1,0,0,2,2;
//move array
int d[maxn][maxn][3];

int bfs()

    memset(d,-1,sizeof d); d[st.r][st.c][st.lie]=0;
    queue<node>q; q.push(st);
    while(!q.empty())
    
        node u=q.front(); q.pop();
        if(u.r==ed.r&&u.c==ed.c&&u.lie==ed.lie) return d[u.r][u.c][u.lie];
        node v;
        for(int i=0;i<4;++i)
        
            v.r=u.r+r_move[u.lie][i], v.c=u.c+c_move[u.lie][i], v.lie=lie_move[u.lie][i];
            if(!valid(v)||d[v.r][v.c][v.lie]!=-1) continue;
            d[v.r][v.c][v.lie]=d[u.r][u.c][u.lie]+1;
            q.push(v);
        
    
    return -1;


int main()

    while(scanf("%d%d",&n,&m)==2 && n)
    
        for(int i=1;i<=n;++i) scanf("%s",a[i] + 1);
        findsted();
        int ans=bfs();
        if(ans==-1) printf("Impossible\n");
        else printf("%d\n",ans);
//      printf("st(%d,%d,%d),ed(%d,%d,%d)\n",st.r,st.c,st.lie,ed.r,ed.c,ed.lie);
    
    return 0;

以上是关于代码:(bfs模板)立体推箱子的主要内容,如果未能解决你的问题,请参考以下文章

立体推箱子2 Poj3323(可打表)

《算法竞赛进阶指南》0x25广度优先搜索 推箱子游戏 双重BFS

hdu1254 推箱子 搜索水题(bfs+bfs)

[GDOI2015]推箱子(状压bfs)

HDU1254--推箱子(BFS+DFS)

HDU 1254 推箱子(BFS加优先队列)