C++ 数据结构之水洼的数量算法

C++ 数据结构之水洼的数量算法

问题描述

有一个矩阵区域,其中包含了若干个“水洼”,每个水洼是由相邻的“水滴”组成的区域。其中,相邻的“水滴”指的是上下左右四个方向上位置相邻的“.”,而不是斜对角线方向。

例如,下面的矩阵区域中,连续的“.”就构成了两个水洼:

X . . X .
X . . X .
. X X . .
. . . X .

现在,给定一个这样的矩阵,编写一个程序,计算其中的水洼数量。

解题思路

本题的基本思路是:遍历矩阵中的每个位置,如果当前位置是“.”并且还没有被访问过,就从该位置开始进行深度优先搜索(DFS),找到与该位置相邻且为“.”的所有位置,将它们标记为已经访问过,并继续向下进行DFS。最终,每次对未访问过的“.”进行DFS就可以找到一个新的水洼,最终得到的DFS深度总数就是水洼的大小。

// 定义矩阵大小
#define MAXN 1001

// 定义矩阵和标记数组
char mat[MAXN][MAXN];
bool vis[MAXN][MAXN];

// DFS函数进行搜索,并标记已经访问过的位置
void dfs(int x, int y) {
    // 标记当前位置为已经访问过
    vis[x][y] = true;
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    for(int i = 0; i < 4; ++i) {
        int nx = x + dx[i], ny = y + dy[i];
        // 判断是否越界或者不是水洼
        if(nx >= 0 && nx < n && ny >= 0 && ny < m && mat[nx][ny] == '.'&& !vis[nx][ny]) {
            dfs(nx, ny);
        }
    }
}

int main() {
    // 读入矩阵的大小和矩阵本身
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; ++i) {
        scanf("%s", mat[i]);
    }
    // 初始化标记数组
    memset(vis, false, sizeof(vis));
    int count = 0;
    // 遍历每个位置
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            // 如果是 "." 并且还没有被遍历过,就进行DFS
            if(mat[i][j] == '.' && !vis[i][j]) {
                count++; // 计数器加1
                dfs(i, j);
            }
        }
    }
    printf("%d\n", count); // 输出水洼的数量
    return 0;
}

其中,mat数组表示矩阵,它的每一行对应一个字符串,而每个字符串中的每个字符表示该位置上的“水滴”或者其他障碍物。vis数组表示标记数组,它表示每个位置是否已经被遍历过。

下面是两个具体的例子。

示例说明

示例 1

4 5
X . . X .
X . . X .
. X X . .
. . . X .

输入以上矩阵后,程序应该输出:

2

这是因为该矩阵中包含两个水洼。

示例 2

3 3
. . .
. . .
. . .

输入以上矩阵后,程序应该输出:

0

这是因为该矩阵中没有水洼。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ 数据结构之水洼的数量算法 - Python技术站

(1)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C++程序的五大内存分区实例详解

    当我们编写C++程序时,系统会默认给程序分配内存,这些内存被分为五个不同的区域,每个区域用途不同,下面我们来详细介绍一下这五个区域的作用。 代码区(文字常量区) 代码区主要用来存放程序的执行代码,这部分内存是只读的,并且在程序启动时就已经固定分配好了。在一个C++程序中,所有的函数、语句都被转换成了二进制码,并被存储在代码区中。代码区还包括存储在程序中的字符…

    C 2023年5月23日
    00
  • C 程序 按升序排列数字

    下面我将为你详细讲解如何使用 C 语言编写一个程序,实现对一组数字按升序排列的功能。在这个过程中,我将提供两条示例说明,帮助你更好地理解。 一、题目描述 编写一个 C 语言程序,实现对一组数值按升序排列的功能。程序输入一个整数数组,长度不超过 100,输出数组按升序排列后的结果。 二、实现思路 我们可以使用 C 语言中的冒泡排序算法来实现对一组数字的升序排列…

    C 2023年5月9日
    00
  • C++11的for循环,以及范围Range类的简单实现

    C++11的for循环和范围(Range)类是在C++11标准中引入的新特性。C++11的for循环允许我们使用更加简洁的语法来遍历数组、容器、等其他可迭代的对象,而范围(Range)类则提供了一种更加直观、可读性更好的方法来表示一个对象的范围。 C++11的for循环 使用C++11的for循环,可以通过以下简洁的语法来遍历数组: int arr[] = …

    C 2023年5月22日
    00
  • Win7 64位旗舰版系统打开应用程序提示“发生未知的软件异常0xc06d007e”的解决方法

    以下是详细讲解“Win7 64位旗舰版系统打开应用程序提示“发生未知的软件异常0xc06d007e”的解决方法”的完整攻略,希望能帮助到您。 问题背景 当我们使用 Win7 64位旗舰版系统打开某些应用程序时,可能会出现弹窗提示“发生未知的软件异常0xc06d007e”的错误信息。这种情况可能会导致应用程序无法正常启动,给我们的工作带来不便。 解决方法 出现…

    C 2023年5月23日
    00
  • Win10无法开机0xc0000225错误代码解决方法

    当我们开机时,有时可能会遇到Win10无法开机的问题,面对这种情况,我们需要对问题进行诊断,找到错误原因并解决问题。其中,“Win10无法开机0xc0000225错误代码解决方法”就是我们需要掌握的一种处理方法。 什么是0xc0000225错误代码? 0xc0000225错误代码是指系统启动时,所需要加载的winload.exe文件出现错误或缺失引起的错误。…

    C 2023年5月23日
    00
  • Qt5.9继承QObject创建多线程实例

    Qt5.9 继承 QObject 创建多线程实例的攻略完整步骤如下: 步骤一:继承 QObject 创建对象 首先,我们需要继承 QObject 类,并将实例化的对象移动到新的线程中。可以使用 moveToThread() 函数来完成此操作。示例如下: class Worker : public QObject { Q_OBJECT public: Work…

    C 2023年5月22日
    00
  • C语言自研定时器计划任务语法详解

    下面我将详细讲解“C语言自研定时器计划任务语法详解”的完整攻略。 概述 在C语言中,我们常常需要进行一些定时处理或者周期性任务等操作。为了方便这些操作,我们可以自研一个定时器计划任务,这个任务包含有启动和停止定时器、注册和注销任务、定时器中断处理等功能。下面我们将具体讲解这些功能的实现方法。 启动和停止定时器 启动定时器的方式如下: int timer_st…

    C 2023年5月23日
    00
  • C++友元函数与拷贝构造函数详解

    C++友元函数与拷贝构造函数详解 什么是友元函数? 在 C++ 编程中,有时一个类的方法需要访问该类的私有成员或保护成员,而这些方法不属于该类,此时就需要用到友元函数。 友元函数是被许可访问该类的私有成员或保护成员的函数。当一个函数被声明为友元函数时,它被赋予了访问该类中所有成员变量和函数的特殊权限。 #include <iostream> us…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部