HDU 5025 Saving Tang Monk(bfs+狀壓) 【openjudge】

Saving Tang Monk

問題分析

本題就是屬於拿鑰匙去開門的bfs 類題目。
題意:孫悟空必須拿到n 個鑰匙才能救出唐僧,但是期間如果遇到蛇怪需要多花一分鐘去打敗她們,並且在拿到第i 個鑰匙之前必須先拿到第i1 個鑰匙,問最少的花費時間。

這題就麻煩在三個地方,
一、同種鑰匙可能有多個,拿完鑰匙的地方仍然可以走,所以需要加一維鑰匙的狀態來判重。
二、因爲打敗蛇怪需要多花費時間,所以肯定要優先走不經過蛇怪的最短路,優先隊列解決。
三、打過蛇怪的地方仍然可以走動,所以需要判斷蛇洞裏的蛇怪dead 沒有,所以需要節點加一個打蛇怪的狀態(snake) 。就比如用0,1,2,3,4... 給蛇編號的,判斷i 號蛇怪是否死亡就用當前的狀態snake&(1<<i) ,如果結果等於0則說明i蛇怪還沒有dead ,否則就是dead

#include <bits/stdc++.h>

struct node {
    int x, y, step, snake, key;

    bool operator<(const node &u) const {
        return step > u.step;
    }
};

const int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
bool vis[111][111][11];
char a[111][111];
int n, m, snakeLoc[111][111];

int rec(int stx, int sty, int desx, int desy) {
    std::priority_queue<node> pq;
    node cur, nxt;
    cur.x = stx, cur.y = sty, cur.step = cur.key = cur.snake = 0;
    pq.push(cur);
    while (!pq.empty()) {
        cur = pq.top();
        pq.pop();
        if (cur.x == desx && cur.y == desy && cur.key == m)
            return cur.step;
        for (int i = 0; i < 4; ++i) {
            int tx = cur.x + dir[i][0];
            int ty = cur.y + dir[i][1];
            int key = cur.key, step = cur.step + 1, snake = cur.snake;
            if (a[tx][ty] == cur.key + '1')
                key++;
            if (tx < 0 || tx >= n || ty < 0 || ty >= n || vis[tx][ty][key] || a[tx][ty] == '#')
                continue;
            if (a[tx][ty] == 'S' && ((snake & (1 << snakeLoc[tx][ty])) == 0)) //if it is a alive snake
                step++, snake |= (1 << snakeLoc[tx][ty]);
            vis[tx][ty][key] = 1;
            nxt = {tx, ty, step, snake, key};
            pq.push(nxt);
        }
    }
    return -1;
}

int main() {
    while (~scanf("%d%d", &n, &m) && (n + m)) {
        int stx, sty, desx, desy, cnt = 0;
        memset(vis, 0, sizeof vis);
        memset(snakeLoc, 0, sizeof(snakeLoc));
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j) {
                scanf(" %c", &a[i][j]);
                if (a[i][j] == 'K') stx = i, sty = j;
                if (a[i][j] == 'T') desx = i, desy = j;
                if (a[i][j] == 'S') snakeLoc[i][j] = cnt++;
            }
        int ans = rec(stx, sty, desx, desy);
        if (ans == -1) puts("impossible");
        else printf("%d\n", ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章