给定一个 n \times nn×n 的矩阵,其中矩阵中的每个数字表示这个格子能否到达四周的格子。
每个数字的范围是 0-150−15,即 44 位二进制数。其中,二进制的最低位表示能否到达上面的格子,倒数第二位表示能否到达右面的格子,第二位表示能否到达下面的格子,第一位表示能否到达左面的格子。如果为 11 则为不能到达,如果为 00 则可以到达。
例如,对于 2 \times 42×4的如下矩阵:
1
13 5 5 3
2
13 5 5 6
我们用 -
来代表上下俩个格子不可达,|
来代表左右俩个格子不可达,则可以矩阵理解为如下的图形:
1
#-#-#-#-#
2
| |
3
#—#-#-# #
4
| |
5
#-#-#-#-#
格子上有俩个点 AA,BB,现在我们要计算从 A 点走到 B 点的最短距离。
输入格式
第一个行输入俩个整数 nn mm 代表矩阵的长宽。接下来的 nn 行,每行输入 mm 个整数,代表矩阵的连通性,保证矩阵是合法的。接下来输入四个整数 x1x1, y1y1, x2x2, y2y2。分别代表 A, BA,B 俩点的坐标。(1 \leq x1,x2 \leq n1≤x1,x2≤n,1 \leq y1, y2 \leq m1≤y1,y2≤m)
数据约定:
对于 30% 的数据:1 \le n,m \le 51≤n,m≤5。
对于 100% 的数据:1 \le n,m \le 5001≤n,m≤500。
输出格式
输出一个整数,代表从 AA 点走到 BB 点的最短距离,如果俩个点之间无法到达输出 -1−1。
样例输入
2 4 13 5 5 3 13 5 5 6 1 1 2 1
样例输出
7
这道题直接就暴力广搜找到终点了,用了点c++的构造方法,写的方便些
#include<bits/stdc++.h>
using namespace std;
int f[4][2]={-1,0,0,1,1,0,0,-1};
struct node{
int x,y,num;
node(){
}
node(int x,int y,int num){
this->x = x;
this->y = y;
this->num = num;
}
};
int a[505][505],n,m,res=0xffffff;int v[505][502]={0};
void bfs(int x,int y,int e,int z)
{
queue<node> q;
node s;
q.push(node(x,y,0));
while(!q.empty())
{
s=q.front();
if(s.x==e&&s.y==z)
{
res=min(res,s.num);
return;
}
q.pop();
int d=a[s.x][s.y];
for(int i=0;i<4;i++)
{
if(d&(1<<i))
{
continue;
}
else if(v[s.x+f[i][0]][s.y+f[i][1]]==0){
v[s.x+f[i][0]][s.y+f[i][1]]=1;
q.push(node(s.x+f[i][0],s.y+f[i][1],s.num+1));
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
int x,y,e,z;
cin>>x>>y>>e>>z;
bfs(x,y,e,z);
if(res==0xffffff)
{
cout<<"-1";
}
else
cout<<res;
}