计蒜客--二进制矩阵

25 篇文章 0 订阅
18 篇文章 0 订阅

给定一个 n \times nn×n 的矩阵,其中矩阵中的每个数字表示这个格子能否到达四周的格子。

每个数字的范围是 0-15015,即 44 位二进制数。其中,二进制的最低位表示能否到达上面的格子,倒数第二位表示能否到达右面的格子,第二位表示能否到达下面的格子,第一位表示能否到达左面的格子。如果为 11 则为不能到达,如果为 00 则可以到达。

例如,对于 2 \times 42×4的如下矩阵:

 
 
1
13 5 5 3
2
13 5 5 6

我们用 -来代表上下俩个格子不可达,|来代表左右俩个格子不可达,则可以矩阵理解为如下的图形:

 
 
 
        
1
#-#-#-#-#
2
|       |
3
#—#-#-# #
4
|       |
5
#-#-#-#-#

格子上有俩个点 AABB,现在我们要计算从 A 点走到 B 点的最短距离。

输入格式

第一个行输入俩个整数 nn mm 代表矩阵的长宽。接下来的 nn 行,每行输入 mm 个整数,代表矩阵的连通性,保证矩阵是合法的。接下来输入四个整数 x1x1y1y1x2x2y2y2。分别代表 A, BA,B 俩点的坐标。(1 \leq x1,x2 \leq n1x1,x2n1 \leq y1, y2 \leq m1y1,y2m)

数据约定:

对于 30% 的数据:1 \le n,m \le 51n,m5

对于 100% 的数据:1 \le n,m \le 5001n,m500

输出格式

输出一个整数,代表从 AA 点走到 BB 点的最短距离,如果俩个点之间无法到达输出 -11

样例输入
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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值