牛客或leetcode编程C实现-深度优先探索(敌人数量)

1 题目

有一个地图,大小是N*M,地图被’#‘分割成大小不同的区域,上下左右’.‘表示同一个区域,’.'表示空地,空地上可能有敌人,敌人使用’E’表示。

输入:

  • 第一行输入N, M, K
  • N:表示地图的行数;
  • M:表示地图的列数;
  • K:表示小于K的敌人敌人区域;
  • 后边输入地图中的字符,如’.’ ‘#’ ‘E’

输出:

  • 输出一个小于K的敌人区域个数;

举例:
输入:
3 5 2
…#EE
E.#…
###…

输出:
1
说明:
2表示敌人个数小于2的区域,由于第二列被#分开了,所以地图有2个区域,其中左边区域敌人个数是1,所以结果输出是1。

2 解题思路

从数组头开始遍历所有节点,如从[0][0]遍历他的上下左右是否存在敌人(然后继续嵌套遍历,直到这个区域被遍历完成),有敌人就记录下来,并标记已经遍历的节点。
数组上下左右可以使用如下方式实现:

// 定义上下左右四个方向的偏移量
int dr[] = {-1, 1, 0, 0};
int dc[] = {0, 0, -1, 1};
char map[i][j]

for (int k = 0; k < 4; k++) {
	new_i = i + dr[k];
	new_j = j + dc[k];
	//嵌套遍历
}

实现方法:

#include 
#include 

#define MAX_N 100
#define MAX_M 100

char map[MAX_N][MAX_M];
bool visited[MAX_N][MAX_M];
int N, M, K;

// 定义上下左右四个方向的偏移量
int dr[] = {-1, 1, 0, 0};
int dc[] = {0, 0, -1, 1};

// 深度优先搜索函数,用于找到一个区域内的敌人数量
int dfs(int r, int c) {
	// 嵌套遍历的退出条件1. 超出数组范围退出;2. 墙的地方退出;3. 遍历过的节点退出;
    if (r < 0 || r >= N || c < 0 || c >= M || map[r][c] == '#' || visited[r][c])
        return 0;
	//记录节点是否遍历过,遍历过的节点下次就会在条件判断处退出
    visited[r][c] = true;
    int enemyCount = (map[r][c] == 'E') ? 1 : 0;

    for (int i = 0; i < 4; i++) {
        int newRow = r + dr[i];
        int newCol = c + dc[i];
        enemyCount += dfs(newRow, newCol);
    }

    return enemyCount;
}

int main() {
    // 读取输入
    scanf("%d %d %d", &N, &M, &K);

    for (int i = 0; i < N; i++) {
        scanf("%s", map[i]);
    }

    int result = 0;

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
        	//1. 空地的地方遍历,2. 没有遍历过的节点遍历
            if (map[i][j] == '.' && !visited[i][j]) {
                int enemyInRegion = dfs(i, j);
                if (enemyInRegion < K) {
                    result++;
                }
            }
        }
    }

    // 输出结果
    printf("%d\n", result);

    return 0;
}

你可能感兴趣的:(编程题或面试题,leetcode,c语言,深度优先,算法,面试)