給定 m×n 矩陣(m,n < 100),1 代表水,0 代表陸地。上下左右相鄰的水視為同一水池。求水池個數。多組測試數據。
#include <stdio.h>
#include <string.h>
int s[105][105];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
void dfs(int x, int y) {
s[x][y] = 0; // 標記已訪問
for (int k = 0; k < 4; k++) {
int nx = x + dx[k], ny = y + dy[k];
if (s[nx][ny]) dfs(nx, ny);
}
}
int main() {
int test, m, n, i, j, ans;
scanf("%d", &test);
while (test--) {
scanf("%d%d", &m, &n);
memset(s, 0, sizeof(s));
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
scanf("%d", &s[i][j]);
ans = 0;
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
if (s[i][j]) {
dfs(i, j);
ans++;
}
printf("%d\n", ans);
}
return 0;
}
vis 陣列。scanf("%d") 自動跳過空白。void bfs(int sx, int sy) {
queue<pair<int,int>> q;
q.push({sx, sy});
s[sx][sy] = 0;
while (!q.empty()) {
auto [x, y] = q.front(); q.pop();
for (int k = 0; k < 4; k++) {
int nx = x + dx[k], ny = y + dy[k];
if (s[nx][ny]) {
s[nx][ny] = 0;
q.push({nx, ny});
}
}
}
}
O(m*n),每個格子進隊/遞歸一次。O(m*n),隊列或遞歸棧。輸入:
2 3 4 1 0 0 0 0 0 1 1 1 1 1 0 5 5 1 1 1 1 0 0 0 1 0 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1
輸出:2 和 3。
此題是連通分量計數的標準練習,掌握 DFS/BFS 模板、數組邊界處理、多測試用例循環,是圖論算法入門必經之路。