题意:推箱子,要求箱子移动步骤最小。

题解:双重bfs,先对箱子bfs,然后判断这种bfs是否可达(对人bfs)。题解本来很简单,但是这题数据SPJ方式各种坑,已经说不上坑了,就是错的。网上各种AC代码也是过不了一些数据,例如:

5 5
.....
..###
....T
#B###
#S###

遍历的时候还要限制顺序才能A,好TM无语。

View Code
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<string>
  5 #include<cctype>
  6 using namespace std;
  7 char map[25][25];
  8 const int N=1000000;
  9 struct data
 10 {
 11     int sx,sy,bx,by,step;
 12     string ans;
 13 }Q[2][N];
 14 int dr[][2]={-1,0,1,0,0,-1,0,1},r,c;
 15 char op[]={'n','s','w','e'};
 16 int mark[25][25][4];
 17 bool bfs(int tx,int ty,data &cc)
 18 {
 19     if(tx<1||tx>r||ty<1||ty>c||map[tx][ty]=='#')
 20         return false;
 21     bool fmark[25][25];
 22     memset(fmark,false,sizeof(fmark));
 23     int bx=cc.bx,by=cc.by,st=0,ed=1;
 24     data a,b;
 25     a.sx=cc.sx;a.sy=cc.sy;a.ans=cc.ans;
 26     Q[1][0]=a;
 27     while(st!=ed)
 28     {
 29         a=Q[1][st++];
 30         if(st==N)
 31             st=0;
 32         if(a.sx==tx&&a.sy==ty)
 33         {
 34             cc.ans=a.ans;
 35             cc.sx=tx;cc.sy=ty;
 36             return true;
 37         }
 38         for(int i=0;i<4;i++)
 39         {
 40             b.sx=a.sx+dr[i][0];
 41             b.sy=a.sy+dr[i][1];
 42             if(b.sx>=1&&b.sx<=r&&b.sy>=1&&b.sy<=c&&!(b.sx==bx&&b.sy==by)&&(map[b.sx][b.sy]=='.'||map[b.sx][b.sy]=='T')&&!fmark[b.sx][b.sy])
 43             {
 44                 fmark[b.sx][b.sy]=true;
 45                 b.ans=a.ans+string(1,(char)op[i]);
 46                 Q[1][ed++]=b;
 47                 if(ed==N)
 48                     ed=0;
 49             }
 50         }
 51     }
 52     return false;
 53 }
 54 int main()
 55 {
 56     int st,ed,ca=0;
 57     while(scanf("%d%d",&r,&c)!=EOF)
 58     {
 59         if(r==0&&c==0)
 60             break;
 61         data a,b;
 62         for(int i=1;i<=r;i++)
 63         {
 64             scanf("%s",map[i]+1);
 65             for(int j=1;j<=c;j++)
 66             {
 67                 if(map[i][j]=='S')
 68                 {
 69                     a.sx=i;
 70                     a.sy=j;
 71                     map[i][j]='.';
 72                 }
 73                 else if(map[i][j]=='B')
 74                 {
 75                     a.bx=i;
 76                     a.by=j;
 77                     map[i][j]='.';
 78                 }
 79             }
 80         }
 81         memset(mark,-1,sizeof(mark));
 82         a.step=0;
 83         a.ans="";
 84         Q[0][st=ed=0]=a;
 85         ed++;
 86         memset(mark[a.bx][a.by],0,4*sizeof(int));
 87         printf("Maze #%d\n",++ca);
 88         bool flag=false;
 89         string ans;
 90         while(st!=ed)
 91         {
 92             a=Q[0][st++];
 93             if(st==N)
 94                 st=0;
 95             if(map[a.bx][a.by]=='T')
 96             {
 97                 flag=true;
 98                 ans=a.ans;
 99                 break;
100             }
101             for(int i=0;i<4;i++)
102             {
103                 int x=a.bx+dr[i][0],y=a.by+dr[i][1];
104                 if(x>=1&&x<=r&&y>=1&&y<=c&&(map[x][y]=='.'||map[x][y]=='T')&&(mark[x][y][i]>a.step+1||mark[x][y][i]==-1))
105                 {
106                     b=a;
107                     if(bfs(a.bx-dr[i][0],a.by-dr[i][1],b))
108                     {
109                         b.step++;
110                         b.ans.append(1,(char)toupper(op[i]));
111                         b.sx=b.bx;
112                         b.sy=b.by;
113                         b.bx=x;
114                         b.by=y;
115                         Q[0][ed++]=b;
116                         if(ed==N)
117                             ed=0;
118                         mark[x][y][i]=b.step;
119                     }
120                 }
121             }
122         }
123         if(!flag)
124         {
125             printf("Impossible.\n\n");
126         }
127         else
128         {
129             printf("%s\n\n",ans.c_str());
130         }
131     }
132     return 0;
133 }