题解:这题主要是bfs搜索时的是否搜索这个点的判定条件不太好写,参考了别人的思路写了一个,只要这个点是不同方向不同颜色经过的就可以重复经过,也就是有20种经过情况,只有都走过了才不再走这个点, 用了一个四维数组,记录点的坐标和颜色方向。
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int N = 50;
struct P {
int x, y, face, color, time;
}p;
queue<P> q;
int row, col, flag, x1, x2, y1, y2, vis[N][N][4][5], face1, color1, time1;
char pos[N][N];
int flag1[4] = {-1, 0, 1, 0};
int flag2[4] = {0, 1, 0, -1};
void init() {
memset(vis, 0, sizeof(vis));
memset(pos, 0, sizeof(pos));
face1 = x1 = x2 = y1 = y2 = color1 = time1 = 0;
while (!q.empty())
q.pop();
flag = 0;
}
void bfs() {
p.x = x1;
p.y = y1;
p.face = p.color = p.time = 0;
q.push(p);
vis[x1][y1][0][0] = 1;
while (!q.empty()) {
face1 = q.front().face;
color1 = q.front().color;
time1 = q.front().time;
x1 = q.front().x;
y1 = q.front().y;
q.pop();
if (x1 == x2 && y1 == y2 && color1 == 0) {
flag = 1;
return;
}
// right
p.x = x1;
p.y = y1;
p.face = (face1 + 1) % 4;
p.color = color1;
p.time = time1 + 1;
if (vis[p.x][p.y][p.face][p.color] == 0) {
q.push(p);
vis[p.x][p.y][p.face][p.color] = 1;
}
// left
p.face = (face1 + 3) % 4;
if (vis[p.x][p.y][p.face][p.color] == 0) {
q.push(p);
vis[p.x][p.y][p.face][p.color] = 1;
}
// go ahead
// face up->0, right->1, down->2, left->3
p.face = face1;
p.color = (color1 + 1) % 5;
p.x = x1 + flag1[face1];
p.y = y1 + flag2[face1];
if (p.x < 0 || p.x >= row || p.y < 0 || p.y >= col)
continue;
if (pos[p.x][p.y] != '#' && vis[p.x][p.y][p.face][p.color] == 0) {
q.push(p);
vis[p.x][p.y][p.face][p.color] = 1;
}
}
}
int main() {
char c;
int t = 1;
while (scanf("%d%d", &row, &col) && (col || row)) {
init();
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++) {
scanf("%c", &c);
if (c == '\n') {
j--;
continue;
}
pos[i][j] = c;
if (pos[i][j] == 'S') {
x1 = i;
y1 = j;
}
if (pos[i][j] == 'T') {
x2 = i;
y2 = j;
}
}
bfs();
if (t != 1)
printf("\n");
printf("Case #%d\n", t++);
if (flag)
printf("minimum time = %d sec\n", time1);
else
printf("destination not reachable\n");
}
return 0;
}