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;
}
posted @ 2018-01-30 20:47  不想吃WA的咸鱼  阅读(209)  评论(0编辑  收藏  举报