题目链接
题意:一自行车的轮子被分成5个扇区,涂了5种不同颜色。自行车每1秒要么骑到下一个格子,要么左转或者右转90。。一开始自行车面向北,颜色为绿,到达目标格时,必须触底颜色为绿,但朝向无限制。求到达目标格的最短时间。
思路:判重数组多加两维,分别为朝向和颜色,之后就可以用BFS求最少时间了。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int MAXN = 30; const int dx[] = {-1, 0, 1, 0}; const int dy[] = {0, 1, 0, -1}; struct node{ node (int xx, int yy, int dd, int cc, int tt) { x = xx; y = yy; d = dd; c = cc; t = tt; } int x, y, d, c, t; }; char g[MAXN][MAXN]; int m, n, sx, sy, ex, ey; int vis[MAXN][MAXN][6][6]; int bfs() { queue<node> q; while (!q.empty()) q.pop(); node s(sx, sy, 0, 0, 0); q.push(s); memset(vis, 0, sizeof(vis)); vis[sx][sy][0][0] = 1; while (!q.empty()) { node u = q.front(); q.pop(); if (u.x == ex && u.y == ey && u.c == 0) return u.t; for (int i = 0; i < 4; i++) { node v = u; if (i == u.d) { v.x = u.x + dx[i]; v.y = u.y + dy[i]; v.c = (u.c + 1) % 5; v.t = u.t + 1; if (v.x < 0 || v.x >= n || v.y < 0 || v.y >= m || g[v.x][v.y] == '#') continue; if (!vis[v.x][v.y][v.d][v.c]) { vis[v.x][v.y][v.d][v.c] = 1; q.push(v); } } else if ((u.d + 1) % 4 == i || (u.d + 3) % 4 == i){ if (!vis[v.x][v.y][i][v.c]) { vis[v.x][v.y][i][v.c] = 1; v.d = i; v.t = u.t + 1; q.push(v); } } } } return -1; } int main() { int t = 1, flag = 0; while (scanf("%d%d", &n, &m) && n && m) { for (int i = 0; i < n; i++) scanf("%s", g[i]); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (g[i][j] == 'S') { sx = i; sy = j; } if (g[i][j] == 'T') { ex = i; ey = j; } } } if (flag) printf("\n"); flag = 1; printf("Case #%d\n", t++); int ans = bfs(); if (ans == -1) printf("destination not reachable\n"); else printf("minimum time = %d sec\n", ans); } return 0; }