hdoj 5040 bfs

本文介绍了一道经典的算法题目——特工如何在被监视的情况下取得目标物品。通过使用广度优先搜索(BFS)并结合优先队列来优化搜索过程,考虑了特工正常移动及使用隐身衣的不同情况。

hdoj 5040

题意:一个特工要去取一个东西,每走一格需要1个单位时间,路上有监视器,监视器监视范围为两格,即所在格和方向格,并且每过一个单位时间会顺时针旋转90度;特工有隐身衣,可以无视监视器移动,但是这样每走一步需要3个单位时间。

思路:就是一个bfs,当移动的时候需要注意当前格和目标格在当前时间是不是被监视着,因为每走一步可能耗费的时间是1秒(正好当前不被监视)2秒(1秒后不被监视)3秒(2秒内一直被监视,直接用隐身衣走),所以还要用优先队列。

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
struct Node {
    int cost, x, y;
    Node() {}
    Node(int a, int b, int c): x(a), y(b), cost(c){}
    bool operator < (const Node &i) const {
        return cost > i.cost;
    }
};

char str[505][505], dir[] = "ESWN";
int d[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
int vis[505][505], n;
bool a[505][505][4];
int bfs(int cx, int cy) {
    priority_queue<Node> pq;
    Node node(cx, cy, 0);
    pq.push(node);
    for(int i = 0; i < 505; i++)
        for(int j = 0; j < 505; j++)
            vis[i][j] = 1 << 30;
    while(!pq.empty()) {
        node = pq.top(), pq.pop();
        if(str[node.x][node.y] == 'T') return node.cost;
        if(node.cost >= vis[node.x][node.y]) continue;
        vis[node.x][node.y] = node.cost;
        for(int i = 0; i < 4; i++) {
            int x = node.x + d[i][0], y = node.y + d[i][1], sec = node.cost;
            if(x < 0 || y < 0 || x >= n || y >= n || str[x][y] == '#') continue;
            if(a[x][y][sec % 4] == false && a[node.x][node.y][sec % 4] == false) {
                Node t(x, y, sec + 1);
                pq.push(t);
            }
            else if(a[x][y][(sec + 1) % 4] == false && a[node.x][node.y][(sec + 1) % 4] == false) {
                Node t(x, y, sec + 2);
                pq.push(t);
            }
            else {
                Node t(x, y, sec + 3);
                pq.push(t);
            }
        }
    }
    return -1;
}
main() {
    int t;
    scanf("%d", &t);
    for(int cas = 1; cas <= t; cas++) {
        int cx, cy;
        memset(a, 0, sizeof a);
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            scanf("%s", str[i]);
            for(int j = 0; str[i][j]; j++) {
                if(str[i][j] == 'M') cx = i, cy = j;
                for(int k = 0; k < 4; k++) {
                    if(str[i][j] == dir[k]) {
                        a[i][j][0] = a[i][j][1] = a[i][j][2] = a[i][j][3] = true;
                        for(int f = 0; f < 4; f++) {
                            int x = i + d[(f + k) % 4][0], y = j + d[(f + k) % 4][1];
                            if(x < 0 || y < 0 || x >= n || y >= n) continue;
                            a[x][y][f] = true;
                        }
                        break;
                    }
                }
            }
        }
        printf("Case #%d: %d\n", cas, bfs(cx, cy));
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值