求矩阵中块的个数
给出一个m*n的矩阵,矩阵中元素为0和1。称位置(x,y)与它上下左右四个位置(x,y-1),(x,y+1),(x-1,y),(x+1,y)是相邻的。如果矩阵中有若干个1是相邻的,则称这些1组成了一个块。计算给定矩阵中块的个数。如:
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个块
思路:BFS。枚举每一个位置元素,如果是0就跳过;如果是1就查询与它相邻的四个元素是否已被遍历过,没有就入队,有就跳过。每个元素设置一个访问位标记它是否已经被访问。
BFS模板:
void BFS(object c){
queue<object> q;
q.push(c);
while(!q.empty()){
去队首元素top;
访问top,并标记为已访问;
q.pop();
将top下层结点中未遍历过的入队。
}
}
注意:使用STL的queue时,元素入队的push操作只是制造了该元素的一个副本并将副本入队,而非对元素本身进行操作。所以,对队列中副本进行修改不会影响元素本身。因此,当需要对队列中元素进行修改时,队列中存放的最好不是元素本身,而是其标号(如果是数组的话则是下标)。
代码:
#include<bits\stdc++.h>
using namespace std;
const int N = 1000;
struct Matrix{
int num;
bool visited;
}matrix[N][N];
struct Node{
int x;
int y;
Node(int a,int b){
x = a;
y = b;
}
};//记录结点位置,方便入队
const int dx[] = {0,0,-1,1};//增量数组,表示上下左右四个方向
const int dy[] = {-1,1,0,0};
int row,col;//行数、列数
int num = 0;//块数目
void BFS(int x,int y){
queue<Node> q;
q.push(Node(x,y));
while(!q.empty()){
Node node = q.front();
matrix[node.x][node.y].visited = true;
q.pop();
for(int i=0;i<4;i++){
int new_x = node.x + dx[i];
int new_y = node.y + dy[i];
if(new_x >= 0 && new_x < row && new_y >= 0 && new_y < col){
if(matrix[new_x][new_y].num == 1 && matrix[new_x][new_y].visited == false){
q.push(Node(new_x,new_y));
}
}
}
}
}
void BFSTraverse(){
for(int i = 0;i < row;i ++){
for(int j = 0;j < col;j ++){
if(matrix[i][j].num == 1 && matrix[i][j].visited == false){
num ++;
BFS(i,j);//把相邻的所有点访问位设置为true
}
}
}
}
int main(){
cin>>row>>col;
for(int i = 0;i < row;i ++){
for(int j = 0;j < col;j ++){
cin>>matrix[i][j].num;
matrix[i][j].visited = false;
//matrix[i][j].x = i;
//matrix[i][j].y = j;
}
}
BFSTraverse();
cout<<num<<endl;
return 0;
}