1.八迷宫
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>//bfs需要用队列来做
using namespace std;
typedef long long ll;//因为体力值太大了需要用ll太存
const int maxn = 505;
int t,mi[maxn][maxn],n,m;
int dy[9] = {-1,-1,-1,0,0,0,1,1,1},dx[9] = {-1,0,1,-1,0,1,-1,0,1};//九个方向
int dd[9],sx,sy,gx,gy;//记录着走每个方向所需要消耗的体力值
ll d[maxn][maxn];
const ll INF = 0x3f3f3f3f3f3f3f3f;//ll类型的无穷大
typedef pair <int , int > P;//类型转换pair成好写的P
void bfs(){
memset(d,INF,sizeof(d));//将每个位置的距离都设为无穷大
queue<P> que;//声明队列
d[sy][sx] = 0;//将起点位置的体力消耗设定为0
que.push(P(sy,sx));//将起点的位置压入队列之中
while(que.size()){//只要队列中还有坐标就继续,因为不知道这个位置的坐标所需要的体力值是否是最小的
P p = que.front();que.pop();//取出队列的第一个坐标
for(int i = 0;i < 9;i++){
int ny = dy[i] + p.first,nx = dx[i] + p.second;
if(ny >= 0 && ny < n && nx >= 0 && nx < m && mi[ny][nx] != 1 && d[ny][nx] > d[p.first][p.second] + dd[i]){
//如果这个位置不是障碍物并且加上走这个方向所需要消耗体力比之前这个位置所需要消耗的体力要少的话就将这个坐标压入到队列之中
que.push(P(ny,nx));
d[ny][nx] = d[p.first][p.second] + dd[i];//并且更新这个位置所需要的最小体力值
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> t;
while(t--){
cin >> n >> m;
for(int i = 0;i < 9;i++) cin >> dd[i];
for(int i = 0;i < n;i++)
for(int j = 0;j < m;j++){
cin >> mi[i][j];
if(mi[i][j] == 2) sy = i,sx = j;
if(mi[i][j] == 3) gy = i,gx = j;
}
bfs();
if(d[gy][gx] != INF) cout << "yes" << " " << d[gy][gx] << '\n';//只要终点所消耗的体力值不为无穷大说明已经走到过这个位置,输出这个位置的消耗即可
else cout << "no" << '\n';
}
return 0;
}