##1.问题描述:
##2.算法分析:
其实这道题目就是一个让我们求出一共有多少个联通块问题;
首先我们要理解怎样才算是联通块,比如单个的1四周被0包围,算作联通块,或者1连着的1两个1算作一个联通块,只要1的上下左右任一个方向存在1都算作一个联通块,比如样例一:
大概就这么个意思。
那么我们该怎么做了,比较容易就想到搜索了,我们枚举每一个位置的元素,如果为0,则跳过,如果为1开始搜索。(基本做法)
我们搜素就使用bfs来向四周扫描(前提不能出界),如果相邻的位置继续向四周扩散,直到整个’1’的块访问完,每次访问完都标记为访问过,然后每次访问check一下坐标是否合法即可。
check函数常用写法:
bool check(int x, int y) {
if (x >= n || x < 0 || y >= m || y < 0) return false; //越界判断
if (mp[x][y] == '0' || vis[x][y]) return false; //判断是否访问过或者不能访问的
return true;
}
然后完成基本的bfs函数即可。
##3.ac代码:
#include <bits/stdc++.h>
using namespace std;
int n, m;
char mp[55][55];
bool vis[55][55];
int dir[4][2] = {{0,1},{0, -1}, {1, 0}, {-1, 0}};
struct node{
int x, y;
node(int xx, int yy) {
x = xx;
y = yy;
}
};
queue<node> q;
bool check(int x, int y) {
if (x >= n || x < 0 || y >= m || y < 0) return false;
if (mp[x][y] == '0' || vis[x][y]) return false;
return true;
}
void bfs(int x, int y) {
q.push(node(x, y));
vis[x][y] = true;
while (!q.empty()) {
node now = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int tx = now.x + dir[i][0];
int ty = now.y + dir[i][1];
if (check(tx, ty)) {
q.push(node(tx, ty));
vis[tx][ty] = true;
}
}
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
memset(vis, false, sizeof(vis));
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%s", mp[i]);
}
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (mp[i][j] == '1' && vis[i][j] == false) {
ans++;
bfs(i, j);
}
}
}
printf("%d\n", ans);
}
return 0;
}
题目链接:相聚
欢迎关注:ly’s Blog