例题1,给出一个m*n的矩阵,矩阵中的元素为0或1,称位置x与其上下左右四个位置是相邻的。若有若干个1相邻,成这些1构成了一个块。例如如下的矩阵中
输入样例:
6 7
0 1 1 1 0 0 1
0 0 1 0 0 0 0
0 0 0 0 1 0 0
0 0 0 1 1 1 0
1 1 1 0 1 0 0
1 1 1 1 0 0 0输出:
4
思路:当发现某一个1满足要求之后(未访问过),使用BFS遍历其周围所有的1,更新qu数组,防止重复访问。
BFS遍历的模板
首先将队首元素push进队列
while(队列不为空){
取出队首元素;
队首元素出队;
遍历其周围节点{
if(满足要求){
入队;
设置为已入队;
}
}
}
#include<cstdio> #include<queue> using namespace std; const int maxn = 100; int matrix[maxn][maxn] = { false }; int qu[maxn][maxn] = { false };//false代表没入过队 int m, n;//函数中需要用到的变量都定义在外面 int X[4] = {0, 1, 0, -1}; int Y[4] = {1, 0, -1, 0}; struct node { int x, y; }Node;//定义了一个node类型的节点Node bool judge(int x, int y) {//判断该点是否是符合的点 //越界 if (x < 0 || x >= n || y < 0 || y >= n) return false; //是0或者访问过 if (matrix[x][y] == 0 || qu[x][y] == 1) return false; return true; } void BFS(int x, int y) {//BFS遍历,扫描周围,将附近的1全部置1 queue<node> Q; qu[x][y] = 1; Node.x = x, Node.y = y; Q.push(Node); while (!Q.empty()) { struct node top = Q.front(); Q.pop(); for (int i = 0; i < 4; i++) { int newX = top.x + X[i];//注意大写 int newY = top.y + Y[i]; if (judge(newX, newY)) { Node.x = newX, Node.y = newY; Q.push(Node); qu[newX][newY] = 1; } } } } int main() { /* 6 7 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 1 1 1 0 1 0 0 1 1 1 1 0 0 0 */ scanf("%d%d", &m, &n); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { scanf("%d", &matrix[i][j]); } } int ans = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (judge(i, j)) { ans++; BFS(i, j); } } } printf("%d\n", ans); return 0; }
例题2,有一个n*m大小的迷宫,*代表墙壁,"."代表平地,S代表起点,T代表终点。求从起点S到达终点T的最少步数。
输入样例:
5 5
.....
.*.*.
.*S*.
.***.
...T*
2 2 4 3输出样例:
11
注意点:
1. inq数组,防止重复访问。
2.struct node{}结构体中添加一个layer属性,记录每个节点的层数。
3.由于换行符‘\n’的存在,读入字符要先getchar(),但是有一个疑问,为什么是在前面getchar,不应该是在后面gerchar吗?
#include<cstdio> #include<queue> using namespace std; const int maxn = 100; int n, m; char matrix[maxn][maxn]; int X[4] = {0, 1, 0, -1}; int Y[4] = { -1, 0, 1, 0 }; int step = 0; int inq[maxn][maxn] = { false };//avoid repeat visit struct node { int x, y; int layer; }S, T, Node; bool judge(int x, int y) {//对点进行check if (matrix[x][y] == '*' || inq[x][y] == 1) return false; if (x < 0 || x >= n || y < 0 || y >= n) return false; return true; } int BFS() { queue<node> Q; Q.push(S); while (!Q.empty()) { node top = Q.front(); Q.pop(); for (int i = 0; i < 4; i++) { int newX = top.x + X[i]; int newY = top.y + Y[i]; if (matrix[newX][newY] == 'T') return top.layer + 1; if (judge(newX, newY)) { Node.x = newX, Node.y = newY; Node.layer = top.layer + 1; Q.push(Node); inq[newX][newY] = 1; } } } return -1; } int main() { /* 5 5 ..... .*.*. .*S*. .***. ...T* 2 2 4 3 */ scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { getchar(); for (int j = 0; j < m; j++) { matrix[i][j] = getchar(); } } scanf("%d%d%d%d", &S.x, &S.y, &T.x, &T.y); S.layer = 0; int step = BFS(); printf("%d", step); return 0; }