蓝书(算法竞赛进阶指南)刷题记录——POJ1475 Pushing Boxes(bfs套bfs)

题目:POJ1475.
题目大意:给定一个 n ∗ m n*m nm的迷宫,现在有一个箱子和一个人,要求让这个人把箱子推到指定位置,求箱子的移动步数最少的方案并输出,若有多个则要求人的移动步数也最少,若还有多个方案则输出任意一个.
1 ≤ n , m ≤ 20 1\leq n,m\leq 20 1n,m20.

这是一道很套路的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;
}

你可能感兴趣的:(蓝书(算法竞赛进阶指南)刷题记录——POJ1475 Pushing Boxes(bfs套bfs))