Uva 10047 - The Monocycle(BFS)
题目链接 https://vjudge.net/problem/UVA-10047
【题意】
独轮车的轮子被分为5个扇形,分别涂上一种不同的颜色,现在有一人骑车行驶在M*N的网格平面上,每个格子的大小刚好使得当车从一个格子骑到下一个格子时,轮子恰好转过一个扇形。有些格子中有障碍,车子不能通过。骑车人从某个格子出发,希望用最短的时间到达目标格,在任何一个格子上,他要么骑到下一个格子,要么左转或者右转90度,其中每项动作都需要1秒钟完成。初始时他面朝北且轮子底面是绿色,要求到达目标格的时候也必须是绿色为底面,朝向没有限制,求最短时间。
【思路】
大白书308页例题,bfs求最短路的基础应用,用4个状态r,c,dir,col表示一个结点的状态,分别是行,列,当前朝向,当前底面颜色,然后用一个四维数组记录完成各种状态的时间,从出发点bfs即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 30;
const int dx[4] = { -1, 0, 1, 0 };
const int dy[4] = { 0, -1, 0, 1 };
//方向 0-北 1-西 2-南 3-东
int n, m;
int sr, sc, er, ec;
char g[maxn][maxn];
int t[maxn][maxn][4][5];
//t[r][c][dir][col]记录到达(r,c)处且方向为dir,底面颜色为col的最短时间
struct node {
int r, c, dir, col;//0代表绿色
node(int rr, int cc, int d, int co) :r(rr), c(cc), dir(d), col(co) {}
};
int bfs() {
queue<node> que;
while (!que.empty()) que.pop();
memset(t, -1, sizeof(t));
que.push(node(sr, sc, 0, 0));
while (!que.empty()) {
node tmp = que.front();
int r = tmp.r;
int c = tmp.c;
int dir = tmp.dir;
int col = tmp.col;
que.pop();
if (tmp.r == er && tmp.c == ec && tmp.col == 0) {
return 1 + t[tmp.r][tmp.c][tmp.dir][tmp.col];
}
//直走
int x = r + dx[dir];
int y = c + dy[dir];
if (x >= 0 && x < n && y >= 0 && y < m && '#' != g[x][y]) {
int nextCol = (col + 1) % 5;
if (t[x][y][dir][nextCol] == -1) {
t[x][y][dir][nextCol] = t[r][c][dir][col] + 1;
que.push(node(x, y, dir, nextCol));
}
}
//左右转
int nextDir = (dir + 1) % 4;
if (t[r][c][nextDir][col] == -1) {
t[r][c][nextDir][col] = t[r][c][dir][col] + 1;
que.push(node(r, c, nextDir, col));
}
nextDir = ((dir - 1) % 4 + 4) % 4;
if (t[r][c][nextDir][col] == -1) {
t[r][c][nextDir][col] = t[r][c][dir][col] + 1;
que.push(node(r, c, nextDir, col));
}
}
return -1;
}
int main() {
int kase = 0;
while (scanf("%d%d", &n, &m) == 2 && (n + m)) {
if (kase != 0) printf("\n");
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 ('S' == g[i][j]) { sr = i, sc = j; }
else if ('T' == g[i][j]) { er = i, ec = j; }
}
}
int ans = bfs();
printf("Case #%d\n", ++kase);
if (-1 != ans) printf("minimum time = %d sec\n", ans);
else printf("destination not reachable\n");
}
return 0;
}