一个FLAG #07# 油田

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\n", cnt);
        for (int i = 0; i != m; ++i) {
            for (int j = 0; j != n; ++j) {
                printf("%d", idx[i][j]);
            }
            printf("\n");
        }
    } 
    
    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
*/

参考

[1] uva 572 Oil Deposits(DFS遍历图) - 不慌不忙、不急不躁 - CSDN博客

猜你喜欢

转载自www.cnblogs.com/xkxf/p/12567189.html