pushing boxes

#include
using namespace std;
char s1[25][25];
int n,m,cs;
int mp[25][25],fm[25][25][4],fb[25][25][4];
int dx[]={0,1,-1,0},dy[]={1,0,0,-1};
string fx="ESNW",fx1="esnw";
bool valid(int x,int y){return x>0&&x<=n&&y>0&&y<=m;}
struct node{int x,y,dir;}b,pre[25][25][4];
node pre1[25][25];
int bs[25][25];
int bfs1(pair<int,int> s,pair<int,int> t,pair<int,int> box){
    memset(pre1,0,sizeof(pre1));
    queue q;
    while(!q.empty())q.pop();
    for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)bs[i][j]=-1;
    bs[s.first][s.second]=0;q.push((node){s.first,s.second,0});
    while(!q.empty()){
        node tmp=q.front();q.pop();
        if(tmp.x==t.first&&tmp.y==t.second)return bs[t.first][t.second];
        for(int i=0;i<4;++i){
            int nx=tmp.x+dx[i],ny=tmp.y+dy[i];
            if(!valid(nx,ny))continue;
            if(bs[nx][ny]!=-1||(nx==box.first&&ny==box.second)||mp[nx][ny])continue;
            bs[nx][ny]=bs[tmp.x][tmp.y]+1;
            pre1[nx][ny]=(node){tmp.x,tmp.y,i};
            q.push((node){nx,ny,0});
        }
    }
    return -1;
}
queue q;
bool bfs(node s,node t){
     while(!q.empty())q.pop();
     for(int i=0;i<4;++i){
          int nx=b.x-dx[i],ny=b.y-dy[i];
          if(!valid(nx,ny)||mp[nx][ny])continue;
         int pr=bfs1(make_pair(s.x,s.y),make_pair(nx,ny),make_pair(b.x,b.y));
         if(pr<0)continue;
         fm[b.x][b.y][i]=pr;
         fb[b.x][b.y][i]=0;
         q.push((node){b.x,b.y,i});
     }
     while(!q.empty()){
         node tmp=q.front();q.pop();
         if(tmp.x==t.x&&tmp.y==t.y)return true;
         for(int i=0;i<4;++i){
             int nx=tmp.x+dx[i],ny=tmp.y+dy[i];
             if(!valid(nx,ny))continue;
             if(fb[nx][ny][i]!=-1||mp[nx][ny])continue;
             int pr=bfs1(make_pair(tmp.x-dx[tmp.dir],tmp.y-dy[tmp.dir]),make_pair(nx,ny),make_pair(tmp.x-dx[i],tmp.y-dy[i]));
             if(pr<0)continue;
             fm[nx][ny][i]=min(fm[nx][ny][i],fm[tmp.x][tmp.y][tmp.dir]+pr+1);
             fb[nx][ny][i]=fb[tmp.x][tmp.y][tmp.dir]+1;
             pre[nx][ny][i]=tmp;
             q.push((node){nx,ny,i});
          }
     }
}
void print1(int tx,int ty,int dir){
    if(!valid(pre1[tx][ty].x,pre1[tx][ty].y))return;
    print1(pre1[tx][ty].x,pre1[tx][ty].y,pre1[tx][ty].dir);
    cout<<fx1[dir];
}
void print(int nx,int ny,int dir){
    node tmp=pre[nx][ny][dir];
    if(!valid(tmp.x,tmp.y))return;
    print(tmp.x,tmp.y,tmp.dir);
    cout<<fx[dir];
    bfs1(make_pair(tmp.x-dx[tmp.dir],tmp.y-dy[tmp.dir]),make_pair(nx-dx[dir],ny-dy[dir]),make_pair(tmp.x,tmp.y));
    print1(nx-dx[dir],ny-dy[dir],dir);
}
void solve(){
    memset(fm,-1,sizeof(fm));
    memset(fb,-1,sizeof(fb));
    for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)for(int k=0;k<4;++k)pre[i][j][k]=(node){0,0,0};
    node s,t;
    for(int i=1;i<=n;++i)scanf("%s", s1[i]+1),fill(mp[i]+1,mp[i]+n+1,0);
    for(int i=1;i<=n;++i)
     for(int j=1;j<=m;++j)
      if(s1[i][j]=='S')s.x=i,s.y=j;
      else if(s1[i][j]=='B')b.x=i,b.y=j;
      else if(s1[i][j]=='T')t.x=i,t.y=j;
      else if(s1[i][j]=='#')mp[i][j]=1;
    printf("Maze #%d\n",++cs);
    if(!bfs(s,t))puts("Impossible.");
    else{
        int ans=1e9,ansi;
        for(int i=0;i<4;++i)
         if(fb[t.x][t.y][i]1)
          ans=fb[t.x][t.y][i],ansi=i;
        bfs1(make_pair(s.x,s.y),make_pair(t.x-dx[ansi],t.y-dy[ansi]),make_pair(b.x,b.y));
        print1(t.x-dx[ansi],t.y-dy[ansi],ansi);
        print(t.x,t.y,ansi);
        cout<<endl;
    }
}
int main(){
    while(cin>>n>>m&&n&&m)solve();
}

目前进度:只差了输出部分

你可能感兴趣的:(pushing boxes)