题
例题6-12 油田。完整题目见参考[1]。
#include<cstdio> #include<cstring> const int MAXN = 100 + 5; char pic[MAXN][MAXN]; // 存原图 int m, n, idx[MAXN][MAXN]; // m 和 n 用来存行和列 // idx用来存 某点的连通分量编号。例如两个格子编号都是1,那么它们是连通的。 void dfs(int r, int c, int id); int main() { while (scanf("%d%d", &m, &n) == 2 && m && n) { for (int i = 0; i != m; ++i) { scanf("%s", pic[i]); } memset(idx, 0, sizeof(idx)); int cnt = 0; // 统计 + 编号, 一举两得。 for (int i = 0; i != m; ++i) { for (int j = 0; j != n; ++j) { // idx[i][j] == 0 这个格子还没dfs过 // pic[i][j] == '@' 这是一个可以dfs的格子 if (idx[i][j] == 0 && pic[i][j] == '@') { dfs(i, j, ++cnt); } } } printf("cnt: %d ", cnt); for (int i = 0; i != m; ++i) { for (int j = 0; j != n; ++j) { printf("%d", idx[i][j]); } printf(" "); } } return 0; } void dfs(int r, int c, int id) { if (r < 0 || r >= m || c < 0 || c >= n) return; // 出界 if (idx[r][c] > 0 || pic[r][c] != '@') return; // 已访问或不可访问 idx[r][c] = id; // 给格子编号 // 向 8 个方向 进军。 // -1 -1, -1 0, -1 1, 0 -1, // 0 1, 1 -1, 1 0, 1 1 // 0 0 排除掉了 但是感觉 不排除也无所谓。 for (int dr = -1; dr <= 1; ++dr) { for (int dc = -1; dc <= 1; ++dc) { if (dr != 0 || dc != 0) { dfs(r + dr, c + dc, id); } } } } /* Sample Input 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ Sample Output cnt: 2 00001 02201 02001 22201 22001 */