码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-10-07 11:36:17      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:const   ++i   break   flag   bfs   ++   ||   c++   include   

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

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

#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 node{int 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模板)立体推箱子

标签:const   ++i   break   flag   bfs   ++   ||   c++   include   

原文地址:https://www.cnblogs.com/tztqwq/p/11629633.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!