版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
最简单的BFS,只不过每个点带上颜色和方向即可,注意题目说的是左转和右转90°,转向的时候是原地不动
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define MAXN 30
using namespace std;
#define NORTH 0
#define SOUTH 1
#define WEST 2
#define EAST 3
#define INF 1000000
char mp[MAXN][MAXN];
int n,m;
struct Point {
int x,y,dir,step,color;
};
int dir[4][3][2] = {{{-1,0},{0,0},{0,0}},{{1,0},{0,0},{0,0}},{{0,-1},{0,0},{0,0}},{{0,1},{0,0},{0,0}}};
bool used[MAXN][MAXN][4][5];
int sx,sy,tx,ty;
queue<Point> q;
void clear_q() {
while(!q.empty()) q.pop();
}
int cal_dir(int dir,int i) {
if(dir==NORTH&&i==0) return NORTH;
if(dir==NORTH&&i==1) return WEST;
if(dir==NORTH&&i==2) return EAST;
if(dir==SOUTH&&i==0) return SOUTH;
if(dir==SOUTH&&i==1) return EAST;
if(dir==SOUTH&&i==2) return WEST;
if(dir==WEST&&i==0) return WEST;
if(dir==WEST&&i==1) return SOUTH;
if(dir==WEST&&i==2) return NORTH;
if(dir==EAST&&i==0) return EAST;
if(dir==EAST&&i==1) return NORTH;
if(dir==EAST&&i==2) return SOUTH;
}
int main() {
int kase = 1;
while(scanf("%d%d",&n,&m) != EOF) {
memset(used,0,sizeof(used));
if(n==0&&m==0) break;
if(kase!=1) printf("\n");
for(int i = 0;i < n;i++) scanf("%s",mp+i);
for(int i = 0;i < n;i++)
for(int j = 0;j < m;j++) {
if(mp[i][j] == 'S') {
sx = i;
sy = j;
}
if(mp[i][j] == 'T') {
tx = i;
ty = j;
}
}
clear_q();
q.push((Point){sx,sy,NORTH,0,3});
used[sx][sy][NORTH][3] = true;
int res = INF;
while(!q.empty()) {
Point cur = q.front();
q.pop();
if(cur.x == tx && cur.y == ty && cur.color == 3) {
res = cur.step;
clear_q();
break;
}
for(int i = 0;i < 3;i++) {
int xx = cur.x+dir[cur.dir][i][0];
int yy = cur.y+dir[cur.dir][i][1];
if(xx<0||xx>=n||yy<0||yy>=m) continue;
if(mp[xx][yy] == '#') continue;
int dir = cal_dir(cur.dir,i);
int color = (cur.color+4)%5;
if(i!=0) {
color = cur.color;
}
if(used[xx][yy][dir][color]) continue;
q.push((Point){xx,yy,dir,cur.step+1,color});
used[xx][yy][dir][color] = true;
}
}
printf("Case #%d\n",kase++);
if(res == INF) {
printf("destination not reachable\n");
} else {
printf("minimum time = %d sec\n",res);
}
}
return 0;
}