题面
题意
给出一副只有一个箱子的推箱子游戏的地图,输出路径.没有则输出"Impossible."
路径要保证箱子移动次数最小,在此条件下,人移动次数最小.
方法
因为求最小次数,故用BFS
因为考虑到要箱子移动次优先,而不是人,故直接搜人怎么移动必然会出错
因而我们可以给每次移动加一个权,人移动的代价是1,箱子是1000,并将结果存储在一个优先队列中,这样就能保证箱子移动次数最少,再用宽搜即可
注意:每输出完一组数据后要空一行.
代码
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define fi first
#define se second
#define PP pair<pair<int,int>,pair<int,int> >
#define P pair<int,PP>
#define people_x fi.fi
#define people_y fi.se
#define box_x se.fi
#define box_y se.se
#define N 1000
using namespace std;
int m,n,px,py,bx,by,zx,zy,nx,ny,nbx,nby,dir[4][2]= {-1,0,1,0,0,-1,0,1},quan,rr,T;
char a[30][30],res[10000],str[25],ans[30][30][30][30];
priority_queue<P,vector<P>,greater<P> >pq;
P tmp,now;
PP pri[30][30][30][30],tmp2,k,start;
bool have,vis[30][30][30][30];
int main()
{
int i,j,l;
while(~scanf("%d%d",&m,&n))
{
T++;
if(!m&&!n) return 0;
have=0;
memset(vis,0,sizeof(vis));
while(!pq.empty()) pq.pop();
for(i=1; i<=m; i++)
{
scanf("%s",str+1);
for(j=1; j<=n; j++)
{
a[i][j]=str[j];
if(a[i][j]=='T')
{
zx=i;
zy=j;
}
if(a[i][j]=='B')
{
bx=i;
by=j;
}
if(a[i][j]=='S')
{
px=i;
py=j;
}
}
}
printf("Maze #%d\n",T);
tmp.first=0;
tmp2.box_x=bx;
tmp2.box_y=by;
tmp2.people_x=px;
tmp2.people_y=py;
tmp2;
tmp.second=tmp2;
start.fi.fi=start.fi.se=start.se.fi=start.se.se=-1;
pri[tmp2.people_x][tmp2.people_y][tmp2.box_x][tmp2.box_y]=start;
vis[px][py][bx][by]=1;
pri[tmp2.people_x][tmp2.people_y][tmp2.box_x][tmp2.box_y]=start;
pq.push(tmp);
while(!pq.empty()&&!have)
{
now=tmp=pq.top();
pq.pop();
tmp2=tmp.second;
bx=tmp2.box_x;
by=tmp2.box_y;
px=tmp2.people_x;
py=tmp2.people_y;
if(bx==zx&&by==zy)
{
rr=0;
k=tmp2;
while(pri[k.fi.fi][k.fi.se][k.se.fi][k.se.se]!=start)
{
rr++;
res[rr]=ans[k.fi.fi][k.fi.se][k.se.fi][k.se.se];
k=pri[k.fi.fi][k.fi.se][k.se.fi][k.se.se];
}
for(i=rr; i>=1; i--)
{
printf("%c",res[i]);
}
printf("\n");
have=1;
break;
}
for(i=0; i<=3; i++)
{
quan=1;
nx=px+dir[i][0];
ny=py+dir[i][1];
nbx=bx;
nby=by;
if(a[nx][ny]=='#'||nx<1||nx>m||ny<1||ny>n) continue;
if(nx==bx&&ny==by)
{
nbx+=dir[i][0];
nby+=dir[i][1];
quan=N;
}
if(a[nbx][nby]=='#'||nbx<1||nbx>m||nby<1||nby>n) continue;
tmp2.box_x=nbx;
tmp2.box_y=nby;
tmp2.people_x=nx;
tmp2.people_y=ny;
tmp.second=tmp2;
tmp.first=now.first+quan;
if(vis[tmp2.people_x][tmp2.people_y][tmp2.box_x][tmp2.box_y])
continue;
vis[tmp2.people_x][tmp2.people_y][tmp2.box_x][tmp2.box_y]=1;
pri[tmp2.people_x][tmp2.people_y][tmp2.box_x][tmp2.box_y]=now.second;
if(i==0) ans[tmp2.people_x][tmp2.people_y][tmp2.box_x][tmp2.box_y]= quan==N?'N':'n';
if(i==1) ans[tmp2.people_x][tmp2.people_y][tmp2.box_x][tmp2.box_y]= quan==N?'S':'s';
if(i==2) ans[tmp2.people_x][tmp2.people_y][tmp2.box_x][tmp2.box_y]= quan==N?'W':'w';
if(i==3) ans[tmp2.people_x][tmp2.people_y][tmp2.box_x][tmp2.box_y]= quan==N?'E':'e';
pq.push(tmp);
}
}
if(!have)
{
printf("Impossible.\n");
}
puts("");
}
}