题目链接。
题意:
一自行车的轮子被分成5个扇区,涂了5种不同颜色。自行车每1秒要么骑到下一个格子,要么左转或者右转90。。一开始自行车面向北,颜色为绿,到达目标格时,必须触底颜色为绿,但朝向无限制。求到达目标格的最短时间。
分析:
在原来的二维,增加两个附加因素:朝向和颜色。然后普通BFS就可以了。
AC代码如下:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> using namespace std; const int maxn = 30; const int color = 5; const int dir = 4; int dx[] = {-1, 0, 1, 0}; int dy[] = {0, 1, 0, -1}; int n, m, kase; char G[maxn][maxn]; bool vis[maxn][maxn][dir][color]; struct node{ int x, y, d, c; int step; node(int x, int y, int d, int c, int step): x(x), y(y), d(d), c(c), step(step) {} }; int bfs(int sx, int sy, int ex, int ey){ memset(vis, false, sizeof(vis)); queue<node> q; q.push(node(sx, sy, 0, 0, 0)); vis[sx][sy][0][0] = true; while(!q.empty()) { node pre = q.front(); q.pop(); if(pre.x == ex && pre.y == ey && pre.c == 0){ return pre.step; } for(int d=0; d<4; d++) { if(d == pre.d){ int x = pre.x+dx[d]; int y = pre.y+dy[d]; int c = (pre.c+1)%color; int s = pre.step+1; if(x < 0 || x >= n || y < 0 || y >= m) continue; if(G[x][y] == '#' || vis[x][y][d][c]) continue; vis[x][y][d][c] = true; q.push(node(x, y, d, c, s)); } else if((pre.d+1)%dir == d || (pre.d+dir-1)%dir == d){ if(vis[pre.x][pre.y][d][pre.c]) continue; vis[pre.x][pre.y][d][pre.c] = true; q.push(node(pre.x, pre.y, d, pre.c, pre.step+1)); } } } return -1; } int main(){ int sx, sy, ex, ey; kase = 0; while(scanf("%d%d", &n, &m) == 2){ if(n == 0 && m == 0) break; 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; } else if(G[i][j] == 'T') { ex = i; ey = j; } } } int ans = bfs(sx, sy, ex, ey); if(kase) putchar('\n'); if(ans == -1) printf("Case #%d\ndestination not reachable\n", ++kase); else printf("Case #%d\nminimum time = %d sec\n", ++kase, ans); } return 0; }