POJ-1475:Pushing Boxes(嵌套bfs或bfs+A*算法)
来源:互联网 发布:红外图像处理算法 编辑:程序博客网 时间:2024/05/29 04:58
题目链接:点击打开链接
题目大意:
一个人要将箱子推到终点,输出推的最少次数的路径,若最少次数相同,输出步数最少。
解题思路:
刚上来没看清题目,以为就是步数最少,刷刷刷敲完发现样咧没过,但是我的代码结果比他还短,以为样例错了,神tm就交了一发,然后wa了。。。
后来仔细看了一下题目,原来是推的次数最少。想了一下,那么肯定要对箱子bfs,对箱子bfs的过程中对人的位置进行bfs,因为要推箱子的话,只有一个位置能推。那么对当前人的位置到这个位置bfs就好,实现稍微注意一下。还听说这道题是假特判,不清楚,反正我是没遇到啥问题。总体来说的话呢就是个嵌套bfs,但是不知道为啥,大佬做法跟我一样但是人家大佬是0msA的,我需要200+ms,可能是代码太过丑陋。。。
这题还有第二种做法,就是利用A星算法,A星算法其实最主要的就是确定优先级的问题。。。
这道题我想了一下,就把我第一次理解错题意的代码拿了出来,然后在struct 里面加上两个 关键字 push step 一个是推箱子次数,一个是总步数,手写好优先级,让推箱子次数少的在前面,如果次数相等就让步数少的在前面。再把队列改为优先队列,然后就A了Orz,但是用时1000+ms,可能是我写的问题,不过感觉这种方法确实没有嵌套bfs快。。。
以下贴两次的代码。。。
首先是嵌套bfs,时间200+ms
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <vector>#include <queue>#include <map>#include <algorithm>#include <set>#include <functional>#define rank ra#define lson rt<<1#define rson rt<<1|1#define pb push_back#define hash hahausing namespace std;typedef long long ll;int n,m;bool vis[25][25][25][25]; //人箱状态bool v[25][25]; //对人单独bfs 人的状态char ma[25][25];int dx[4]={-1,1,0,0};int dy[4]={0,0,-1,1};int px,py,vx,vy,ex,ey; //分别记录人箱子起始位置和终点string ans;struct nodes //对人单独bfs用的struct{ int x,y; string dir;};struct node //箱子bfs{ int px,py,vx,vy; string dir;};char vc(int i){ if(i==0) return 'N'; if(i==1) return 'S'; if(i==2) return 'W'; return 'E';}char vs(int i){ if(i==0) return 'n'; if(i==1) return 's'; if(i==2) return 'w'; return 'e';}bool check(int x,int y) //检查点是否合理{ if(x>=1&&x<=n&&y>=1&&y<=m&&ma[x][y]!='#') return 1; return 0;}string bfs1(int sx,int sy,int kx,int ky,int gx,int gy) //对人单独bfs 注意箱子也不能通过{ memset(v,0,sizeof(v)); queue<nodes> que; nodes st; st.x=sx;st.y=sy; que.push(st); v[st.x][st.y]=1; string res="Impossible."; nodes k1; while(!que.empty()) { nodes k=que.front(); que.pop(); if(k.x==kx&&k.y==ky) { res=k.dir; break; } for(int i=0;i<4;i++) { int xx=k.x+dx[i]; int yy=k.y+dy[i]; if(check(xx,yy)&&v[xx][yy]==0&&(xx!=gx||yy!=gy)) { k1.x=xx; k1.y=yy; k1.dir=k.dir+vs(i); que.push(k1); v[xx][yy]=1; } } } return res;}void bfs(){ memset(vis,0,sizeof(vis)); queue<node> que; node st; st.px=px;st.py=py; st.vx=vx;st.vy=vy; que.push(st); vis[px][py][vx][vy]=1; //记录初始位置 ans="Impossible."; node k1; while(!que.empty()) { node k=que.front(); que.pop(); if(k.vx==ex&&k.vy==ey) { ans=k.dir; break; } for(int i=0;i<4;i++) { int xx=k.vx+dx[i]; //判断箱子能否被人在后面推一格 int yy=k.vy+dy[i]; int bx=k.vx-dx[i]; int by=k.vy-dy[i]; if(check(xx,yy)&&check(bx,by)&&vis[k.vx][k.vy][xx][yy]==0) { string tem,re; k1.px=k.vx;k1.py=k.vy; k1.vx=xx;k1.vy=yy; re=bfs1(k.px,k.py,bx,by,k.vx,k.vy); //注意传箱子的位置 if(re==ans) //人不能到达则跳过 continue; tem=k.dir+re; k1.dir=tem+vc(i); que.push(k1); vis[k.vx][k.vy][xx][yy]=1; } } }}int main(){ int kase=0; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf(" %c",&ma[i][j]); if(ma[i][j]=='S') { px=i; py=j; } if(ma[i][j]=='B') { vx=i; vy=j; } if(ma[i][j]=='T') { ex=i; ey=j; } } } bfs(); printf("Maze #%d\n",++kase); cout<<ans<<endl; printf("\n"); } return 0;}
A星算法,其实也就是正常bfs中加了关键字和优先队列。
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <vector>#include <queue>#include <map>#include <algorithm>#include <set>#include <functional>#define rank ra#define lson rt<<1#define rson rt<<1|1#define pb push_back#define hash hahausing namespace std;typedef long long ll;int n,m;bool vis[25][25][25][25]; //记录状态char ma[25][25]; int dx[4]={0,-1,1,0};int dy[4]={1,0,0,-1};int px,py,vx,vy,ex,ey;string ans;struct node{ int px,py,vx,vy; int push,step; //分别为推箱子次数和总步数 string dir; bool operator<(const node &g) const //手写优先级将小的放在队列前面 { if(push==g.push) return step>g.step; return push>g.push; }};char vc(int i){ if(i==0) return 'E'; if(i==1) return 'N'; if(i==2) return 'S'; return 'W';}char vs(int i){ if(i==0) return 'e'; if(i==1) return 'n'; if(i==2) return 's'; return 'w';}void bfs(){ memset(vis,0,sizeof(vis)); priority_queue<node> que; //使用优先队列 node st; st.px=px;st.py=py; st.vx=vx;st.vy=vy; st.step=st.push=0; que.push(st); vis[px][py][vx][vy]=1; ans="Impossible."; node k1; while(!que.empty()) { node k=que.top(); que.pop(); if(k.vx==ex&&k.vy==ey) { ans=k.dir; break; } for(int i=0;i<4;i++) { int xx=k.px+dx[i]; int yy=k.py+dy[i]; if(xx<1||xx>n||yy<1||yy>m||ma[xx][yy]=='#'||vis[xx][yy][k.vx][k.vy]) continue; if(xx==k.vx&&yy==k.vy) //如果人走的这一步推动了箱子 { int tx=xx+dx[i]; int ty=yy+dy[i]; if(tx<1||tx>n||ty<1||ty>m||ma[tx][ty]=='#'||vis[xx][yy][tx][ty]) continue; k1.px=xx;k1.py=yy; k1.vx=tx;k1.vy=ty; k1.push=k.push+1; //推箱子次数+1 k1.step=k.step+1; k1.dir=k.dir+vc(i); que.push(k1); vis[xx][yy][tx][ty]=1; } else //正常bfs { k1.px=xx;k1.py=yy; k1.vx=k.vx;k1.vy=k.vy; k1.push=k.push; k1.step=k.step+1; k1.dir=k.dir+vs(i); que.push(k1); vis[xx][yy][k.vx][k.vy]=1; } } }}int main(){ int kase=0; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf(" %c",&ma[i][j]); if(ma[i][j]=='S') { px=i; py=j; } if(ma[i][j]=='B') { vx=i; vy=j; } if(ma[i][j]=='T') { ex=i; ey=j; } } } bfs(); printf("Maze #%d\n",++kase); cout<<ans<<endl; printf("\n"); } return 0;}
阅读全文
0 0
- POJ-1475:Pushing Boxes(嵌套bfs或bfs+A*算法)
- Pushing Boxes (poj 1475 嵌套bfs)
- POJ 1475 Pushing Boxes(嵌套BFS)
- POJ 1475 Pushing Boxes 嵌套BFS -
- 【POJ1475】Pushing Boxes-A*(或BFS?)
- poj 1475 Pushing Boxes(bfs)
- POJ 1475 Pushing Boxes(BFS)
- POJ 1475 Pushing Boxes(BFS)
- POJ-1475-Pushing Boxes(BFS)
- POJ 1475 Pushing Boxes 【A*bfs套bfs】
- hdu 1254 推箱子/poj 1475 Pushing Boxes(推箱子经典问题,BFS嵌套BFS)
- poj 1475 Pushing Boxes(推箱子游戏,bfs+bfs)
- POJ 1475 Pushing Boxes 搜索- 两重BFS
- poj 1729 Jack and Jill 1376 Robot 1324 Holedox Moving 1475 Pushing Boxes bfs + a*
- POJ 1475 Pushing Boxes (双重BFS/推箱子游戏)
- POJ 1475 Pushing Boxes(推箱子游戏 内嵌BFS)
- 双重 BFS —— POJ 1475 Pushing Boxes
- POJ Pushing Boxes 优先队列BFS
- [题解] CodeForces 429B Working out
- Mybatis的输入输出映射和全局配置文件
- Number Sequence
- Java面试题全集(中)
- 如何通过牛顿方法解决Logistic回归问题 By 机器之心2017年8月09日 16:30 本文介绍了牛顿方法(Newton's Method),以及如何用它来解决 logistic 回归。log
- POJ-1475:Pushing Boxes(嵌套bfs或bfs+A*算法)
- 找出三个最大值demo
- window应用程序靠消息驱动、Marshal类、StructureToByte、ByteToStructure
- MathGL在Windows下的编译
- 二叉树的一些性质
- Java面试题全集(下)
- 安卓开发集成SMS短信验证码模块,mob平台
- Block内存管理
- Tomcat载入js文件时中文乱码,后台传值都正常