1. 程式人生 > 實用技巧 >勝利大逃亡(續) - 狀壓bfs

勝利大逃亡(續) - 狀壓bfs

在之前一題的基礎上加了個條件,也就是說如果當然位置的值是門,那麼需要有鑰匙才能經過。、
按照前一題的思路,進行狀壓,設定vis[][][1 << 10]陣列,表示當前點以及當前資訊是否訪問過。

如果說是小寫字母,也就是鑰匙,就直接把當前狀態或運算一下,讓當前點繼承或後的值,然後加入佇列即可
如果說是大寫字母,也就是門,那麼就需要進行判斷,判斷我對應的鑰匙是否存在,用和運算子號,注意此時,直接繼承之前的資訊即可,不需要把key變成和之後的結果
如果是普通的點,就直接繼承即可
傳送門

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int N = 25;
char s[N][N];
bool vis[N][N][1 << 11];
int dir[][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int n, m, t;
int sx, sy, ex, ey;
struct Node{
    int x, y, key, step;
};
bool check(int x, int y){
    if(x < 1 || x > n || y < 1 || y > m || s[x][y] == '*') return 0;
    return 1;
}
int bfs(){
    queue<Node> q;
    Node now; now.x = sx, now.y = sy, now.key = 0, now.step = 0;
    q.push(now);
    while(!q.empty()) {
        Node u = q.front(); q.pop();
        if(u.step >= t) return -1;
        if(u.x == ex && u.y == ey) return u.step;
        for(int i = 0; i < 4; i++) {
            int xx = dir[i][0] + u.x;
            int yy = dir[i][1] + u.y;
            if(!check(xx, yy)) continue;
            Node nex;
            nex.step = u.step + 1;
            nex.x = xx, nex.y = yy;
            nex.key = u.key;
            if(s[xx][yy] >= 'a' && s[xx][yy] <= 'z') {
                int temp = s[xx][yy] - 'a';
                nex.key = u.key | (1 << temp);
            }else if(s[xx][yy] >= 'A' && s[xx][yy] <= 'Z') {
                int temp = s[xx][yy] - 'A';
                int key = u.key & (1 << temp);
                if(!key) continue;
            } 
            if(vis[xx][yy][nex.key]) continue;
            vis[xx][yy][nex.key] = 1;
            q.push(nex);
        }
    }
    return -1;
}
int main(){
    while(~scanf("%d%d%d", &n, &m, &t)) {
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i++) scanf("%s", s[i] + 1);
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(s[i][j] == '@') sx = i, sy = j;
                if(s[i][j] == '^') ex = i, ey = j;
            }
        }
        printf("%d\n", bfs());
    }
    return 0;
}