机考E卷200分题 - 战场索敌

题目描述

有一个大小是N*M的战场地图,被墙壁 ‘#’ 分隔成大小不同的区域,上下左右四个方向相邻的空地 ‘.’ 属于同一个区域,只有空地上可能存在敌人’E”,

请求出地图上总共有多少区域里的敌人数小于K。

输入描述

第一行输入为N,M,K;

  • N表示地图的行数,M表示地图的列数, K表示目标敌人数量
  • N,M<=100

之后为一个NxM大小的字符数组。

输出描述

敌人数小于K的区域数量

示例1

输入

3 5 2
..#EE
E.#E.
###..
1234

输出

1
1

说明

地图被墙壁分为两个区域,左边区域有1个敌人,右边区域有3个敌人,符合条件的区域数量是1

解题思路

整体思路是,遍历地图中的每个位置,如果该位置未被访问过且不是墙壁,则调用dfs函数计算以该位置为起点的区域中敌人的数量,如果该数量小于目标敌人数量k,则将区域数量加1。最后,输出区域数量。

我们将地图矩阵存储在一个二维字符数组matrix中。

接下来,我们需要初始化一个二维布尔数组visited,用于标记地图中的每个位置是否已经被访问过。初始化visited为false。

然后,我们定义一个深度优先搜索函数dfs,用于计算以位置(i, j)为起点的区域中敌人的数量。在dfs函数中,我们首先将位置(i, j)标记为已访问,并根据该位置的值判断是否为敌人,如果是,则将计数器count加1。然后,我们使用一个栈来保存待访问的位置。在每一次循环中,我们从栈中取出一个位置(pos),并遍历其上下左右四个相邻位置。如果相邻位置在地图范围内、未被访问过且不是墙壁,则将其标记为已访问,并根据其值判断是否为敌人,如果是,则将计数器count加1,并将该位置加入到栈中。最后,返回计数器count。

接下来,我们定义主函数main。在主函数中,我们首先读取地图的行数n、列数m和目标敌人数量k。然后,根据地图的行数n和列数m初始化visited和matrix数组。接下来,我们遍历地图中的每个位置,如果该位置已经被访问过或者是墙壁,则跳过。否则,调用dfs函数计算以该位置为起点的区域中敌人的数量,如果该数量小于目标敌人数量k,则将区域数量加1。最后,输出区域数量。

Java

import java.util.Scanner;

public class Main {
    // 定义地图的行数、列数和目标敌人数量
    private static int n, m, k;
    // 定义存储地图的二维字符数组
    private static char[][] matrix;
    // 定义标记访问状态的二维数组
    private static int[][] visited;
    // 记录当前区域的敌人数量
    private static int enemyCount;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取地图的行数n、列数m和目标敌人数量k
        n = scanner.nextInt();
        m = scanner.nextInt();
        k = scanner.nextInt();

        // 初始化地图矩阵和访问标记数组
        matrix = new char[n][m];
        visited = new int[n][m];

        // 读取地图矩阵数据
        for (int i = 0; i < n; i++) {
            String row = scanner.next();
            for (int j = 0; j < m; j++) {
                matrix[i][j] = row.charAt(j); // 逐字符读取地图
            }
        }

        int ans = 0; // 初始化符合条件的区域计数

        // 遍历地图中的每个位置
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                // 如果当前格子已经访问过或是墙壁,跳过
                if (visited[i][j] != 0 || matrix[i][j] == '#') {
                    continue;
                }
                enemyCount = 0; // 初始化当前区域的敌人计数
                dfs(i, j); // 深度优先搜索该区域
                // 如果该区域的敌人数小于k,则该区域符合条件
                ans += enemyCount < k ? 1 : 0;
            }
        }

        // 输出符合条件的区域数量
        System.out.println(ans);
    }

    // 深度优先搜索函数,从(i, j)位置开始计算敌人数
    public static void dfs(int i, int j) {
        visited[i][j] = 1; // 将当前位置标记为已访问

        // 如果当前位置是敌人,增加敌人计数
        if (matrix[i][j] == 'E') {
            enemyCount++;
        }

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

        // 遍历四个相邻方向
        for (int[] offset : offsets) {
            int newX = i + offset[0];
            int newY = j + offset[1];

            // 检查相邻位置是否在地图范围内,未访问过且不是墙壁
            if (newX >= 0 && newX < n && newY >= 0 && newY < m && visited[newX][newY] == 0 && matrix[newX][newY] != '#') {
                dfs(newX, newY); // 递归访问相邻位置
            }
        }
    }
}

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576

Python

import sys

def dfs(i, j):
    visited[i][j] = 1  # 标记当前位置已访问

    if matrix[i][j] == 'E':  # 如果当前位置是敌人,增加敌人数量
        global enemyCount
        enemyCount += 1

    offsets = [[-1, 0], [1, 0], [0, -1], [0, 1]]  # 定义上下左右四个方向

    # 遍历四个方向,检查相邻格子
    for offset in offsets:
        newX = i + offset[0]
        newY = j + offset[1]

        # 检查相邻格子是否在范围内、未访问且不是墙壁
        if newX >= 0 and newX < n and newY >= 0 and newY < m and visited[newX][newY] == 0 and matrix[newX][newY] != '#':
            dfs(newX, newY)  # 递归访问相邻格子

# 读取地图行数、列数和目标敌人数量
n, m, k = map(int, input().split())

matrix = []  # 初始化地图矩阵
visited = [[0] * m for _ in range(n)]  # 初始化访问标记数组

# 读取地图数据
for _ in range(n):
    row = input()
    matrix.append(list(row))

ans = 0  # 初始化符合条件的区域计数

# 遍历地图的每个格子
for i in range(n):
    for j in range(m):
        # 如果该格子已访问或是墙壁,跳过
        if visited[i][j] != 0 or matrix[i][j] == '#':
            continue
        enemyCount = 0  # 初始化敌人数量
        dfs(i, j)  # 深度优先搜索
        # 如果该区域敌人数小于k,则符合条件
        ans += 1 if enemyCount < k else 0

# 输出符合条件的区域数量
print(ans)

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647

JavaScript

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

let n, m, k;
let matrix = [];
let visited = [];

rl.on('line', (line) => {
  if (!n) {
    [n, m, k] = line.split(' ').map(Number);  // 读取地图行数、列数和敌人数量
    visited = Array.from({ length: n }, () => Array(m).fill(false));  // 初始化访问标记数组
  } else {
    matrix.push(line.split(''));  // 读取地图矩阵
  }
}).on('close', () => {
  const enemyCount = { count: 0 };  // 用于记录敌人数量的对象

  // 深度优先搜索函数
  function dfs(i, j) {
    visited[i][j] = true;  // 标记为已访问

    if (matrix[i][j] === 'E') {
      enemyCount.count++;  // 如果是敌人,增加计数
    }

    const offsets = [[-1, 0], [1, 0], [0, -1], [0, 1]];  // 定义四个方向

    // 遍历四个相邻方向
    for (const offset of offsets) {
      const newX = i + offset[0];
      const newY = j + offset[1];

      // 检查是否在地图范围内且未访问
      if (newX >= 0 && newX < n && newY >= 0 && newY < m && !visited[newX][newY] && matrix[newX][newY] !== '#') {
        dfs(newX, newY);  // 递归搜索
      }
    }
  }

  let ans = 0;  // 记录符合条件的区域数量

  // 遍历地图的每个格子
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < m; j++) {
      if (visited[i][j] || matrix[i][j] === '#') {
        continue;  // 如果已访问或是墙壁,跳过
      }
      enemyCount.count = 0;  // 初始化敌人计数
      dfs(i, j);  // 深度优先搜索
      ans += enemyCount.count < k ? 1 : 0;  // 判断是否符合条件
    }
  }

  console.log(ans);  // 输出结果
});

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960

C++

#include <iostream>
#include <vector>
using namespace std;

int n, m, k;  // 地图行数、列数和目标敌人数量
vector<vector<char>> matrix;  // 存储地图的二维数组
vector<vector<int>> visited;  // 标记访问状态的二维数组
int enemyCount;  // 记录当前区域敌人的数量

// 深度优先搜索函数,从(i, j)开始计算该区域的敌人数
void dfs(int i, int j) {
    visited[i][j] = 1;  // 标记当前位置为已访问
    
    if (matrix[i][j] == 'E') {
        enemyCount++;  // 如果当前位置是敌人,增加计数
    }
    
    vector<vector<int>> offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};  // 定义四个方向

    // 遍历相邻的四个方向
    for (vector<int> offset : offsets) {
        int newX = i + offset[0];
        int newY = j + offset[1];
        
        // 检查新位置是否在地图范围内,且未访问过且不是墙壁
        if (newX >= 0 && newX < n && newY >= 0 && newY < m && visited[newX][newY] == 0 && matrix[newX][newY] != '#') {
            dfs(newX, newY);  // 递归访问相邻位置
        }
    }
}

int main() {
    cin >> n >> m >> k;  // 读取地图行数、列数和目标敌人数量
    
    matrix.resize(n, vector<char>(m));  // 初始化地图矩阵
    visited.resize(n, vector<int>(m));  // 初始化访问标记数组
    
    // 读取地图数据
    for (int i = 0; i < n; i++) {
        string row;
        cin >> row;
        for (int j = 0; j < m; j++) {
            matrix[i][j] = row[j];  // 将地图数据存入矩阵
        }
    }
    
    int ans = 0;  // 记录符合条件的区域数量
    
    // 遍历地图的每个格子
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (visited[i][j] != 0 || matrix[i][j] == '#') {
                continue;  // 如果已经访问或是墙壁,跳过
            }
            enemyCount = 0;  // 初始化敌人计数
            dfs(i, j);  // 深度优先搜索
            ans += enemyCount < k ? 1 : 0;  // 判断该区域是否符合条件
        }
    }
    
    cout << ans << endl;  // 输出符合条件的区域数量
    
    return 0;
}

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

C语言

#include <stdio.h>
#include <stdlib.h>

int n, m, k;  // 地图行数、列数和目标敌人数量
char **matrix;  // 存储地图的二维数组
int **visited;  // 标记访问状态的二维数组
int enemyCount;  // 记录当前区域敌人的数量

// 深度优先搜索函数,从(i, j)开始计算该区域的敌人数
void dfs(int i, int j) {
    visited[i][j] = 1;  // 标记当前位置为已访问

    if (matrix[i][j] == 'E') {
        enemyCount++;  // 如果当前位置是敌人,增加计数
    }

    int offsets[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};  // 定义四个方向

    // 遍历相邻的四个方向
    for (int d = 0; d < 4; d++) {
        int newX = i + offsets[d][0];
        int newY = j + offsets[d][1];

        // 检查新位置是否在地图范围内,且未访问过且不是墙壁
        if (newX >= 0 && newX < n && newY >= 0 && newY < m && visited[newX][newY] == 0 && matrix[newX][newY] != '#') {
            dfs(newX, newY);  // 递归访问相邻位置
        }
    }
}

int main() {
    // 读取地图行数、列数和目标敌人数量
    scanf("%d %d %d", &n, &m, &k);

    // 初始化地图矩阵
    matrix = (char **)malloc(n * sizeof(char *));
    for (int i = 0; i < n; i++) {
        matrix[i] = (char *)malloc((m + 1) * sizeof(char));  // 额外分配1个字符存储字符串终止符
    }

    // 初始化访问标记数组
    visited = (int **)malloc(n * sizeof(int *));
    for (int i = 0; i < n; i++) {
        visited[i] = (int *)malloc(m * sizeof(int));
    }

    // 读取地图数据
    for (int i = 0; i < n; i++) {
        scanf("%s", matrix[i]);  // 直接读取一整行字符串
    }

    int ans = 0;  // 记录符合条件的区域数量

    // 遍历地图的每个格子
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (visited[i][j] != 0 || matrix[i][j] == '#') {
                continue;  // 如果已经访问或是墙壁,跳过
            }
            enemyCount = 0;  // 初始化敌人计数
            dfs(i, j);  // 深度优先搜索
            ans += (enemyCount < k) ? 1 : 0;  // 判断该区域是否符合条件
        }
    }

    printf("%d\n", ans);  // 输出符合条件的区域数量

    // 释放动态分配的内存
    for (int i = 0; i < n; i++) {
        free(matrix[i]);
        free(visited[i]);
    }
    free(matrix);
    free(visited);

    return 0;
}

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778

完整用例

用例1
3 5 2
..#EE
E.#E.
###..
1234
用例2
4 4 3
..#.
E..E
.#E.
..##
12345
用例3
2 2 1
E#
.#
123
用例4
2 3 2
E#E
.#.
123
用例5
3 3 0
...
...
...
1234
用例6
5 5 3
..#..
E...E
.#...
...#.
##..#
123456
用例7
6 6 2
.#....
.#....
.#....
.#....
.#....
E######
1234567
用例8
4 5 4
...#.
.#..#
.#...
.#..E
12345
用例9
5 6 3
...##.
.#...#
.#.#..
E.#...
.#.#E#
123456
用例10
3 4 1
..#.
.#.E
.#..
1234
#牛客创作赏金赛#

主要记录自己的刷题日常,学而时习之。

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务