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\n",k++);
120         if(bfs1()) printf("%s\n\n",bnow.ans.c_str());//少个换行wa了一次
121            else printf("Impossible.\n\n");
122 }
123   return 0;
124 }
时间: 2024-12-15 08:43:32

poj 1475 Pushing Boxes 推箱子(双bfs)的相关文章

poj 1475 Pushing Boxes

http://poj.org/problem?id=1475 Pushing Boxes Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 4662   Accepted: 1608   Special Judge Description Imagine you are standing inside a two-dimensional maze composed of square cells which may or

HDU 1475 Pushing Boxes

Pushing Boxes Time Limit: 2000ms Memory Limit: 131072KB This problem will be judged on PKU. Original ID: 147564-bit integer IO format: %lld      Java class name: Main Special Judge Imagine you are standing inside a two-dimensional maze composed of sq

hdu 1254(推箱子游戏bfs+状态标记)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1254 推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5181    Accepted Submission(s): 1439 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N

suseoj 1212: 推箱子问题(bfs)

1212: 推箱子问题 时间限制: 1 Sec  内存限制: 128 MB提交: 60  解决: 13[提交][状态][讨论版][命题人:liyuansong] 题目描述 码头仓库是划分为n×m个格子的矩形阵列.有公共边的格子是相邻格子.当前仓库中有的格子是空闲的,有的格子则已经堆放了沉重的货物.由于堆放的货物很重,单凭仓库管理员的力量是无法移动的.仓库管理员有一项任务:要将一个小箱子推到指定的格子上去.管理员可以在仓库中移动,但不能跨过已经堆放了货物的格子.管理员站在与箱子相对的空闲格子上时,

2016暑假集训补题系列——POJ 1475

POJ 1475 Pushing Boxes 题意:模拟推箱子游戏给出一个二维图,S表示人的位置,B表示箱子位置,T表示目标位置.要求最短输出路径大写字母代表推,小写字母代表走. 思路:BFS+BFS,首先对箱子进行BFS,每一次在加入新的节点时对人再进行一次BFS,找到他走到需要推箱子的地方的最小路径.(最开始不知道怎么记录路径,之前也几乎不用String,结果如此好用,还可以直接加...) #include<cstdio> #include<algorithm> #includ

poj 1475 推箱子

bfs是一层层的遍历下去,每多一层即为多走一步,因此只要遇到T就停,此时肯定是最小步数. 所以这两层bfs应为,先对箱子的最少步数进行bfs,从而求出推箱子所用最少步数: 然后箱子bfs内部嵌入人的bfs,从而箱子每走一步,判断一下这个移动能否由人来完成(由箱子的移动倒推人应该在的位置,看这个位置是否合理). 一.http://tech.artyoo.me/?p=282 1 #include <map> 2 #include <set> 3 #include <queue&g

【15.4.1 Pushing Boxes】双重bfs

[15.4.1 Pushing Boxes] 想象您正站在一个二维的迷宫中,迷宫由是正方形的方格组成,这些方格可能被岩石阻塞,也可能没有.您可以向北,南,东或西一步移到下一个方格.这些移动被称为行走(walk). 在一个空方格中放置了一个箱子,您可以挨着箱子站着,然后按这个方向推动这个箱子,这个箱子就可以被移动到一个临近的位置.这样的一个移动被称为推(push).除了推以外,箱子不可能用其他的方法被移动,这就意味着如果您把箱子推到一个角落,您就永远不能再把它从角落中推出. 一个空格被标识为目标空

POJ-1475 Pushing Boxes (BFS+优先队列)

Description Imagine you are standing inside a two-dimensional maze composed of square cells which may or may not be filled with rock. You can move north, south, east or west one cell at a step. These moves are called walks. One of the empty cells con

poj1475 Pushing Boxes(BFS)

题目链接 http://poj.org/problem?id=1475 题意 推箱子游戏.输入迷宫.箱子的位置.人的位置.目标位置,求人是否能把箱子推到目标位置,若能则输出推的最少的路径,如果有多条步数相同的推的最少的路径,则输出总步数(人走的步数+推箱子的步数)最少的那条路径:若不能把箱子推到目标位置,则输出Impossible. 思路 先求出箱子到目标位置的最短路径(bfs_box),在bfs1推箱子的过程中,根据推的方向和箱子的位置得到人的位置,再求得人到达这个位置的最短路(bfs_per