poj 1475 Pushing Boxes 推箱子(双bfs)

题目链接:http://poj.org/problem?id=1475

一组测试数据:

7 3

###

.T.

.S.

#B#

...

...

...

结果: 

//解题思路:先判断盒子的四周是不是有空位,如果有,则判断人是否能到达盒子的那一边,能的话,把盒子推到空位处,然后继续

AC代码:

  1 //解题思路:先判断盒子的四周是不是有空位,如果有,则判断人是否能到达盒子的那一边,能的话,把盒子推到空位处,然后继续
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<cstring>
  6 #include<queue>
  7 #include<string>
  8 #include<cmath>
  9 using namespace std;
 10 int bx,by,sx,sy,tx,ty;
 11 int m,n,dir[][2]={-1,0,1,0,0,-1,0,1};//注意题目要求的是n、s、w、e的顺序,因为这个wa了一次
 12 char op[]={'n','s','w','e'};
 13 bool mark[25][25][4];//标记箱子四周的位置时候已被用过
 14 int vis[25][25];//标记人走过的位置
 15 char  map[25][25];
 16 struct BB//盒子
 17 {
 18     int x,y,SX,SY;//SX,SY表示当前箱子固定了,人所在的位置
 19     string ans;
 20 }bnow,beed;
 21 struct YY//
 22 {
 23     int x,y;
 24     string ans;
 25 }ynow,yeed;
 26 char up(char c)
 27 {
 28     return (c-'a'+'A');
 29 }
 30 //aa,bb 表示当前盒子的位置;ss,ee表示起点;
 31 bool bfs2(int s,int e,int aa,int bb,int ss,int ee)//寻找当前人,是否能够到达盒子指定的位置;
 32 {
 33     queue<YY>yy;
 34     if(s<0 || s>m || e<0 || e>n || map[s][e] == '#') return false;
 35     ynow.x = ss; ynow.y = ee; ynow.ans="";
 36     memset(vis,0,sizeof(vis));
 37     vis[aa][bb] =1;//不能经过盒子
 38     vis[ss][ee] = 1;//起点标记为
 39     yy.push(ynow);
 40     while(!yy.empty())
 41     {
 42         ynow = yy.front();
 43         yy.pop();
 44         if(ynow.x == s && ynow.y == e)
 45         {
 46             return true;
 47         }
 48         for(int i=0;i<4;i++)
 49         {
 50             yeed.x = ynow.x+dir[i][0];
 51             yeed.y = ynow.y+dir[i][1];
 52             if(yeed.x>0 && yeed.x<=m && yeed.y>0 && yeed.y<=n && !vis[yeed.x][yeed.y] && map[yeed.x][yeed.y]!='#')
 53             {
 54                 yeed.ans = ynow.ans+op[i];//记录走过的路径
 55                 vis[yeed.x][yeed.y] = 1;
 56                 yy.push(yeed);
 57             }
 58         }
 59     }
 60     return false;
 61 }
 62 bool bfs1()
 63 {
 64    queue<BB>bb;
 65    bnow.x = bx;bnow.y=by;bnow.ans="";
 66    bnow.SX = sx;bnow.SY=sy;
 67    bb.push(bnow);
 68    while(!bb.empty())
 69      {
 70 
 71        bnow=bb.front();
 72        bb.pop();
 73        if(bnow.x == tx && bnow.y==ty)
 74        {
 75            return true;
 76        }
 77        for(int i=0;i<4;i++) //盒子周围的四个方向;
 78        {
 79            beed.x = bnow.x+dir[i][0];
 80            beed.y = bnow.y+dir[i][1];
 81            if(beed.x>0 && beed.x<=m && beed.y>0 && beed.y<=n && !mark[beed.x][beed.y][i] && map[beed.x][beed.y]!='#')
 82            {
 83                if(bfs2(beed.x-2*dir[i][0],beed.y-2*dir[i][1],bnow.x,bnow.y,bnow.SX,bnow.SY))//如果能推到yeed,则需要判断人是否能到达,它的上一个点;
 84                {
 85                     beed.SX = bnow.x;//推完箱子后,人的位置在箱子上
 86                     beed.SY = bnow.y;
 87                     beed.ans=bnow.ans+ynow.ans+up(op[i]);//当前的加上推箱子的加上目前挨着推的;
 88                     mark[beed.x][beed.y][i] = true;
 89                     bb.push(beed);
 90                }
 91            }
 92        }
 93      }
 94    return false;
 95 }
 96 int main()
 97 {
 98 int T,k=1;
 99 while(scanf("%d %d",&m,&n) && m+n)
100 {
101     memset(mark,false,sizeof(mark));
102     for(int i=1;i<=m;i++)
103         for(int j=1;j<=n;j++)
104     {
105         scanf(" %c",&map[i][j]);
106         if(map[i][j] == 'S')
107         {
108             sx=i;sy =j;
109         }
110         if(map[i][j] == 'T')
111         {
112             tx = i;ty = j;
113         }
114         if(map[i][j] == 'B')
115         {
116             bx = i;by = j;
117         }
118     }
119     printf("Maze #%d
",k++);
120         if(bfs1()) printf("%s

",bnow.ans.c_str());//少个换行wa了一次
121            else printf("Impossible.

");
122 }
123   return 0;
124 }
原文地址:https://www.cnblogs.com/lovychen/p/4453147.html