计蒜客-二进制矩阵 BFS

题解: 直接BFS搜即可

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <queue>
#define MAXN 550
using namespace std;
int a[MAXN][MAXN];
int n,m;
struct Node {
	int x,y;// 坐标
	int step; 
};
bool visited[MAXN][MAXN];
int x1,y11,x2,y2;// 这里写y1代码交上去会报编译错误,估计可能是哪个库里面起了个变量名冲突了 
queue<Node> q;
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};

void BFS() {
	Node node = (Node){x1,y11,0};
	visited[x1][y11] = true;
	q.push(node);
	while(!q.empty()) {
		Node top = q.front();
		q.pop();
		// 检查是否已经到终点 
		if(top.x == x2 && top.y == y2) {
			printf("%d\n",top.step);
			exit(0);
		}
		// 遍历4个方向 
		int bit = 1;
		for(int i = 0;i < 4;i++) {
			bit = 1<<i;			
			int xx = top.x + dir[i][0];
			int yy = top.y + dir[i][1];
			// 越界 
			if(xx <= 0 || xx > n || yy <= 0 || yy > m) continue;
			if(a[top.x][top.y] & bit) continue;
			// 避免回溯 
			if(visited[xx][yy]) continue;
			q.push((Node){xx,yy,top.step+1});
			visited[xx][yy] = true;
		}
	}
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= n;i++)
		for(int j = 1;j <= m;j++) {
			scanf("%d",&a[i][j]);
		}
	scanf("%d%d%d%d",&x1,&y11,&x2,&y2);
	if(x1==x2&&y11==y2) {
		printf("0\n");
		return 0;
	}
	BFS();
	printf("-1\n");
	
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BFS(宽度优先搜索)是一种用于遍历或搜索图(特别是无权图或加权非负图)的数据结构算法,它从源节点开始,逐层扩展节点,直到找到目标节点或者遍历完整个图。在使用邻接矩阵表示图时,C语言中实现BFS的基本步骤如下: 1. **邻接矩阵**: 邻接矩阵是一个二维数组,其中行代表起点,列代表终点。如果两个顶点之间有边相连,对应的矩阵元素值为1(通常二进制表示),否则为0。 2. **初始化**: - 初始化一个队列,将起始节点入队。 - 创建一个布尔数组标记已访问过的节点,初始时所有节点标记为未访问。 3. **循环**: - 取出队首节点。 - 对于该节点的每一个相邻节点,如果它们没有被访问过,标记为已访问,然后入队。 - 更新队列和标记数组。 4. **递归调用**: - 如果找到目标节点,返回成功;若队列为空仍没有找到目标,返回失败。 5. **代码实现**: ```c #include <stdio.h> #include <stdbool.h> #define ROWS 5 #define COLS 5 bool visited[ROWS][COLS]; bool found; void bfs(int src, int graph[][COLS], int V) { int i, j; int queue[ROWS * COLS], front = 0, rear = 0; visited[src][src] = true; queue[rear++] = src; while (front != rear) { src = queue[front++]; printf("(%d)", src); for (i = 0; i < V; i++) { if (graph[src][i] && !visited[i][src]) { visited[i][src] = true; queue[rear++] = i; if (i == target) { // 找到目标节点 found = true; break; } } } } if (!found) printf("的目标节点未找到"); } // 使用函数的地方 int main() { int graph[ROWS][COLS] = {/* 图的邻接矩阵 */}; int V = ROWS; // 图中的节点数 int start = 0, target = 4; // 起始和目标节点 bfs(start, graph, V); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值