bfs开标记空间时,一个状态不但要标记所在的位置,还要标记颜色,方向。因此可以开一个4维数组。
每个状态可以转移到3个状态。
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; int M,N; int ox,oy; int dis[30][30][6][4]; char Map[30][30]; int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; bool blk[30][30]; struct node{ int x,y; int c,d; node(){} node(int tx,int ty,int tc,int td):x(tx),y(ty),c(tc),d(td){} }; bool leg(int x,int y){ if(x<0||y<0||x>=M||y>=N||blk[x][y]) return 0; return 1; } int bfs(){ memset(dis,-1,sizeof(dis)); memset(blk,0,sizeof(blk)); queue<node> Q; for(int i=0;i<M;i++){ for(int j=0;j<N;j++){ if(Map[i][j]=='S'){ Q.push(node(i,j,0,0)); dis[i][j][0][0]=0; } if(Map[i][j]=='T'){ ox=i;oy=j;} if(Map[i][j]=='#') blk[i][j]=1; } } while(!Q.empty()){ node cur=Q.front(); Q.pop(); int tx=cur.x+dir[cur.d][0]; int ty=cur.y+dir[cur.d][1]; if(tx==ox&&ty==oy&&cur.c==4) return dis[cur.x][cur.y][cur.c][cur.d]+1; if(leg(tx,ty)&&dis[tx][ty][(cur.c+1)%5][cur.d]==-1){ Q.push(node(tx,ty,(cur.c+1)%5,cur.d)); dis[tx][ty][(cur.c+1)%5][cur.d]=dis[cur.x][cur.y][cur.c][cur.d]+1; } if(dis[cur.x][cur.y][cur.c][(cur.d+1)%4]==-1){ Q.push(node(cur.x,cur.y,cur.c,(cur.d+1)%4)); dis[cur.x][cur.y][cur.c][(cur.d+1)%4]=dis[cur.x][cur.y][cur.c][cur.d]+1; } if(dis[cur.x][cur.y][cur.c][(cur.d+3)%4]==-1){ Q.push(node(cur.x,cur.y,cur.c,(cur.d+3)%4)); dis[cur.x][cur.y][cur.c][(cur.d+3)%4]=dis[cur.x][cur.y][cur.c][cur.d]+1; } } return -1; } int main(){ bool fir=1; int kase=1; while(~scanf("%d%d",&M,&N)){ if(!M&&!N) break; if(fir) fir=0; else printf("\n"); for(int i=0;i<M;i++){ scanf("%s",Map[i]); } int res=bfs(); printf("Case #%d\n",kase++); if(res==-1) printf("destination not reachable\n"); else printf("minimum time = %d sec\n",res); } return 0; } /* 1 3 S#T 10 10 #S.......# #..#.##.## #.##.##.## .#....##.# ##.##..#.# #..#.##... #......##. ..##.##... #.###...#. #.....###T 0 0 */