#94-[真正的BFS]勝利大逃亡
阿新 • • 發佈:2018-12-09
Description
elfness被魔王抓走了,這次魔王把elfness關在一個n*m的地牢裡。地牢的某個地方安裝了一個帶鎖的門,鑰匙藏在地牢的另外一個地方,elfness想要通過這個門,就必須先走到藏鑰匙的地方取鑰匙。剛開始的時候elfness被關在(sx,sy)的位置,而離開地牢的門在(ex,ey)的位置。elfness每分鐘只能從一個位置走到相鄰四個位置中的其中一個。魔王每t分鐘都回地牢視察一次,若發現elfness不在原位置便會把他拎回去。經過若干次的嘗試,elfness已經畫出了整個地牢的地圖。現在請你幫他計算能否再次成功逃亡。只要在魔王下次視察之前走到出口就算離開地牢,如果魔王回來的時候還未到出口都算逃亡失敗。
Input
第一行有三個整數n,m,t。接下來的n行m列為地牢的地圖,其中包括: . 代表路 * 代表牆 @ 代表elfness的起始位置 ^ 代表地牢的出口 A 代表帶鎖的門 a 代表鑰匙
Output
輸出為一行,包含一個整數。對於可以成功逃亡的情況,請輸出至少需要多少分鐘才能離開,如果不能則輸出-1。
Sample Input
4 4 100
@..A
a.*.
***.
^…
Sample Output
11
HINT
【資料範圍】 對於100%的資料,2<=n,m<=20,t>0
[分析]
BFS
一個點如果沒有被訪問過,走;
一個點被沒帶鑰匙訪問過,如果有鑰匙,走。
程式碼:
#include <iostream> #include <queue> #define SIZE 24 using namespace std; struct node { int x, y, costed; }; node current, next1; int visited[SIZE][SIZE]; int dx[4] = {0, 1, 0, -1}; // 四個方向 int dy[4] = {-1, 0, 1, 0}; bool keyed[SIZE][SIZE]; char a[SIZE][SIZE]; queue<node> q; int main(void) { int n, m, t, i, j, k, entrancex, entrancey, exitx, exity, row, column, f = 0; cin >> n >> m >> t; for (i = 1; i <= n; ++i) { for (j = 1; j <= m; ++j) { cin >> a[i][j]; if (a[i][j] == '@') { entrancex = i; entrancey = j; f |= 1; } else if (a[i][j] == '^') { exitx = i; exity = j; f |= 2; } else if (a[i][j] == 'a') { f |= 4; } else if (a[i][j] == 'A') { row = i; column = j; f |= 8; } } } if ((f & 3) != 3) // 沒起點沒終點,不成 { cout << -1 << endl; return 0; } if ((f & 12) == 8) // 沒鑰匙,大門改障礙物 { a[row][column] = '*'; } for (i = 0; i < SIZE; ++i) { for (j = 0; j < SIZE; ++j) { visited[i][j] = -1; if (f & 8 == 0) { keyed[i][j] = true; } else { keyed[i][j] = false; } } } for (i = 0; i <= n + 1; ++i) { a[i][0] = a[i][m+1] = '*'; } for (j = 0; j <= m + 1; ++j) { a[0][j] = a[n+1][j] = '*'; } a[entrancex][entrancey] = '.'; current.x = entrancex; current.y = entrancey; current.costed = 0; visited[current.x][current.y] = 0; keyed[current.x][current.y] = false; q.push(current); while (!(q.empty())) // 基本BFS { current = q.front(); q.pop(); if ((current.x == exitx) && (current.y == exity)) // 到達終點 { if (current.costed < t) // 沒到時間,輸出結果 { cout << current.costed << endl; return 0; } else // 等於或超過限定時間,不成 { cout << -1 << endl; return 0; } } for (k = 0; k < 4; ++k) { next1.x = row = current.x + dx[k]; next1.y = column = current.y + dy[k]; if ((visited[row][column] == -1) || ((visited[row][column] == 0) && (keyed[current.x][current.y]) && (!keyed[row][column]))) { if (a[row][column] == 'a') { keyed[row][column] = true; } if (((a[row][column] != '*') && (a[row][column] != 'A')) || ((a[row][column] == 'A') && (keyed[current.x][current.y]))) { visited[row][column] = 0; next1.x = row; next1.y = column; next1.costed = current.costed + 1; if (keyed[current.x][current.y]) { keyed[row][column] = true; } q.push(next1); } } } } cout << -1 << endl; // 到達不了,不成 return 0; }