##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