题目:POJ1475.
题目大意:给定一个 n ∗ m n*m n∗m的迷宫,现在有一个箱子和一个人,要求让这个人把箱子推到指定位置,求箱子的移动步数最少的方案并输出,若有多个则要求人的移动步数也最少,若还有多个方案则输出任意一个.
1 ≤ n , m ≤ 20 1\leq n,m\leq 20 1≤n,m≤20.
这是一道很套路的BFS套BFS板子,而且还要输出路径.
其实挺好做的,我们在外面BFS出箱子如何移动,然后在外层BFS判断箱子是否可以移动时用一个内层BFS跑路径即可.
输出路径的话每个状态都多存一个字符串记录路径即可.
时间复杂度 O ( n 2 m 2 ) O(n^2m^2) O(n2m2),但是由于记录路径的问题可能复杂度还要更高一点.
代码如下(前面写的几发莫名CE是什么鬼啊):
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define Abigail inline void
typedef long long LL;
const int N=25;
const int dx[4]={0,0,-1,1};
const int dy[4]={1,-1,0,0};
const char box[4]={'E','W','N','S'};
const char per[4]={'e','w','n','s'};
char mp[N+9][N+9];
int n,m,b[N+9][N+9],bb[N+9][N+9],bp[N+9][N+9];
string ans;
struct state{
int bx,by,px,py;
string ans;
state(){bx=by=px=py=0;ans="";}
state(int Bx,int By,int Px,int Py){bx=Bx;by=By;px=Px;py=Py;ans="";}
state(int Px,int Py){bx=0;by=0;px=Px;py=Py;ans="";}
};
int sbx,sby,spx,spy;
bool out_map(int x,int y){return x<1||x>n||y<1||y>m;}
bool bfs2(int bx,int by,int sx,int sy,int tx,int ty,string &str){
if (sx==tx&&sy==ty) {str="";return 1;}
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
bp[i][j]=0;
queue<state>q;
state t,nt;
bp[sx][sy]=1;
q.push(state(sx,sy));
while (!q.empty()){
t=q.front();q.pop();
for (int i=0;i<4;++i){
nt=state(t.px+dx[i],t.py+dy[i]);
if (out_map(nt.px,nt.py)||b[nt.px][nt.py]||bp[nt.px][nt.py]||nt.px==bx&&nt.py==by) continue;
nt.ans=t.ans+per[i];
q.push(nt);
bp[nt.px][nt.py]=1;
if (nt.px==tx&&nt.py==ty) {str=nt.ans;return 1;}
}
}
return 0;
}
bool bfs1(int sbx,int sby,int spx,int spy){
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
bb[i][j]=0;
queue<state>q;
state t,nt;
q.push(state(sbx,sby,spx,spy));
bb[sbx][sby]=1;
while (!q.empty()){
t=q.front();q.pop();
for (int i=0;i<4;++i){
string str="";
nt=state(t.bx+dx[i],t.by+dy[i],t.bx,t.by);
if (out_map(nt.bx,nt.by)||b[nt.bx][nt.by]||bb[nt.bx][nt.by]) continue;
if (!bfs2(t.bx,t.by,t.px,t.py,t.bx-dx[i],t.by-dy[i],str)) continue;
nt.ans=t.ans+str+box[i];
q.push(nt);
bb[nt.bx][nt.by]=1;
if (mp[nt.bx][nt.by]=='T') {ans=nt.ans;return 1;}
}
}
return 0;
}
Abigail into(){
for (int i=1;i<=n;++i){
scanf("%s",mp[i]+1);
for (int j=1;j<=m;++j){
if (mp[i][j]=='S') spx=i,spy=j;
if (mp[i][j]=='B') sbx=i,sby=j;
b[i][j]=mp[i][j]=='#'?1:0;
}
}
}
Abigail outo(int cas){
printf("Maze #%d\n",cas);
if (!bfs1(sbx,sby,spx,spy)) ans="Impossible.";
int siz=ans.size();
for (int i=0;i<siz;++i)
putchar(ans[i]);
puts("\n");
}
int main(){
int cas=0;
while (~scanf("%d%d",&n,&m)&&n+m){
into();
outo(++cas);
}
return 0;
}