您的位置:首页 > 其它

POJ 1475 Pushing Boxes 【A*bfs套bfs】

2017-07-07 00:04 531 查看
点击打开链接

题意:

推箱子,这游戏都玩过吧,没玩过也知道规则吧。

现在就问你把箱子推到指定位置,的最优情况。

这里的最优是:

1.推箱子的次数最少,

2.推箱子次数相同,走的次数最少。

找到该最优解并把路径打出来,推这箱子的移动用大写字母表示,自己走的用小写字母表示。

题解:

bfs套bfs

先搜箱子走的状态,然后搜该状态下人能否到达,

我自己写了一个曼哈顿估值,,,,还是跑了235ms 应该是快了点吧,,,可能是写了假的Astar。。。

#include <cstdio>
#include <cctype>
#include <cstring>
#include <queue>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

int dir[4][2]={-1,0, 1,0, 0,-1, 0,1};/*上下左右*/
char d1[5]="NSWE";
char d2[5]="nswe";
int n,m,d;
char ma[22][22];
int vis[22][22][4];
int vv[22][22];
struct node{
int bx,by;
int px,py;
int push,walk;
int fp;
string way;
bool operator <(const node t)const{
if(t.fp==fp) return walk>t.walk;
return fp>t.fp;
}
}st,ed,box,u,v;
struct nod{
int x,y;
int g,f;
int fx,fy;
string way;
bool operator<(const nod t)const{
return t.f<f;
}
}sp,up,vp,pre;
priority_queue<node>que;
priority_queue<nod>qq;
int get_f(node b,int a){
int ret=abs(b.bx-ed.bx)+abs(b.by-ed.by);
return ret+a;
}
int bfs(int sx,int sy,int ex,int ey){
vp.way="";vp.g=0;
if(sx==ex&&sy==ey) return 1;
memset(vv,0,sizeof(vv));
while(!qq.empty()) qq.pop();
sp.x=sx,sp.y=sy;
sp.g=0;
sp.way="";
vv[sx][sy]=1;
sp.f=abs(sx-ex)+abs(sy-ey);
qq.push(sp);
while(!qq.empty()){
up=qq.top();
qq.pop();
//printf("  pre(%d,%d)->%d\n",up.x,up.y,up.g);
for(int i=0;i<4;++i){
int tx=up.x+dir[i][0];
int ty=up.y+dir[i][1];
if(tx<1||tx>n||ty<1||ty>m) continue;
//if(sx==6&&sy==4) printf("(%d,%d)-%c %d \n",tx,ty,ma[tx][ty],vv[tx][ty]);
if(ma[tx][ty]=='#'||vv[tx][ty]) continue;
vp.x=tx,vp.y=ty;
vp.g=up.g+1;
vp.way=up.way+d2[i];
vp.fx=up.x,vp.fy=up.y;
if(tx==ex&&ty==ey) return 2;
vp.f=vp.g+abs(tx-ex)+abs(ty-ey);
vv[tx][ty]=1;
qq.push(vp);
}
}
return 0;
}

int Astar(){
int flag;
memset(vis,0,sizeof(vis));
while(!que.empty()) que.pop();
st.bx=box.bx;
st.by=box.by;
st.px=pre.x;
st.py=pre.y;
st.push=st.walk=0;
st.fp=get_f(st,0);
que.push(st);
while(!que.empty()){
u=que.top();
que.pop();
if(u.bx==ed.bx&&u.by==ed.by){
cout<<u.way<<endl;
return 1;
}
for(int i=0; i<4; ++i){
int tx=u.bx+dir[i][0];
int ty=u.by+dir[i][1];
if(tx<1||tx>n||ty<1||ty>m||ma[tx][ty]=='#'||vis[tx][ty][i]) continue;
//if(u.bx==4&&u.by==2)printf("box(%d,%d)->%c, %d,%d   pre(%d,%d)->%d----%d\n",u.bx,u.by,ma[tx][ty],tx,ty,u.px,u.py,vis[tx][ty][i],flag);

if(i<2) d=!i;
else if(i==2) d=3;
else d=2;

ma[u.bx][u.by]='#';
//            if(u.bx==4&&u.by==2)
//            for(int ii=1;ii<=7;++ii){
//                for(int jj=1;jj<=11;++jj){
//                    printf("%c ",ma[ii][jj]);
//                }puts("");
//            }
flag=bfs(u.px,u.py,u.bx+dir[d][0],u.by+dir[d][1]);
if(flag){
if(vis[u.bx][u.by][i]) {
ma[u.bx][u.by]='.';
continue;
}//if(u.bx==4&&u.by==2) printf("u.p->(%d %d) u.b->(%d,%d)\n",u.px,u.py,u.bx+dir[d][0],u.by+dir[d][1]);
vis[u.bx][u.by][i]=1;
v.bx=tx,v.by=ty;
v.px=u.bx;v.py=u.by;
v.push=u.push+1;
v.walk=u.walk+vp.g;
v.way=u.way;
if(flag==1) v.way+=d1[i];
else {
v.way+=vp.way;
v.way+=d1[i];
}
v.fp=get_f(v,v.push);
que.push(v);
}

ma[u.bx][u.by]='.';

}
}
return 0;
}
int main(){
int ca = 0;
while(scanf("%d%d", &n, &m)&&(n+m)){

for(int i=1; i<=n; ++i) scanf("%s",ma[i]+1);
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j){
if(ma[i][j]=='S'){
ma[i][j]='.';
pre.x=i,pre.y=j;
}
if(ma[i][j]=='T'){
ma[i][j]='.';
ed.bx=i,ed.by=j;
}
if(ma[i][j]=='B'){
ma[i][j]='.';
box.bx=i,box.by=j;
}
}
printf("Maze #%d\n", ++ca);
if(Astar()) ;
else puts("Impossible.");
puts("");

}
return 0;
}
/*
8 9
#########
#......T#
#.S.....#
##B######
#.......#
#.......#
#.......#
#########
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: