1429 勝利大逃亡(續)
相關演算法:廣度優先搜尋(百度連結)
#include <iostream>
#include <queue>
using namespace std;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; //移動路徑表
int m,n,t;
char map[22][22]; //地圖
struct node{ //點狀態
short x,y;
short key;
short step;
}start,now,temp;
int
int t = 1<<(int)(in-'a'); //鑰匙對應的整數值
return (key & t) ? 0 : t; //檢查是否已經擁有鑰匙
}
bool chkkey(char in, int key){ //檢查是否能開啟該門
return (key>>(int)(in-'A'))&1;
}
void read(){ //讀取地圖
int
for (i=1; i<=m; i++) //畫頂行牆
map[0][i] = '*';
for (i=1; i<=n; i++){
getchar(); //迴避回車字元
map[i][0] = '*';
for (j=1; j<=m; j++){
map[i][j] = getchar();
if (map[i][j] == '@'){ //檢查是否為起點
start.
start.y = j;
}
}
map[i][m+1] = '*';
}
for (i=1; i<=m; i++) //畫底行牆
map[n+1][i] = '*';
start.key = 0; //初始化start點
start.step = 0;
}
int DPS(){ //廣優演算法
queue<node>q;
int x,y,step,key; //臨時狀態
char tp; //當前點的字元號
bool visited[22][22][1024]={false}; //儲存訪問狀態[x][y][鑰匙狀態]
q.push(start); //起始點入列
visited[start.x][start.y][0] = true; //標記起點
while (!q.empty()){
now = q.front();
q.pop();
step=now.step+1; //時間計算
if (step==t) //超時判斷
break;
for(int i=0; i<4; i++){
x=now.x+dir[i][0];
y=now.y+dir[i][1];
key=now.key;
tp = map[x][y];
if (!(tp == '*' || visited[x][y][key])){ //判斷是否為牆壁,是否走過
if (tp >= 'A' && tp <='J'){
if (!chkkey(tp,key)) //判斷是否持有對應鑰匙
continue; //了結該點,執行下一次迴圈
}else if(tp >= 'a' && tp <='j'){
key += transch_2(tp,key); //取得鑰匙
}else if(tp == '^'){
return step; //到達出口,返回使用時間
}
temp.x=x;
temp.y=y;
temp.step=step;
temp.key=key;
q.push(temp); //該步可走,進入佇列
visited[x][y][key] = true; //當前位置標記為已走過
}
}
}
return -1; //無法逃亡,返回-1 }
int main(int argc, char* argv[]){
while (scanf("%d%d%d",&n,&m,&t) != EOF){
read();
printf("%d/n",DPS());
}
return 0;
}