题意:推箱子,要求箱子移动步骤最小。
题解:双重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 }