C语言编程题_3D接雨水

这篇具有很好参考价值的文章主要介绍了C语言编程题_3D接雨水。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

接雨水的题目描述如下。

(1) 2D接雨水: 字节员工是不是个个都会接雨水 ;

(2) 3D接雨水: 407. 接雨水 II ;

(3) 3D接雨水: 字节人都会的 3D接雨水 。

  问题描述

  难度:困难

  给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。

  示例1:

C语言编程题_3D接雨水,百科,IT_百科,IT_C语言和C++语言,c语言,算法,开发语言

  输入:heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]];

  输出:4

  解释:下雨后,雨水将会上图蓝色的方块中。总的接雨水量为1+1+1=4。

  我找到的最好的思路是:把这个看成木桶接水,就像是短板理论。最外层一圈一定接不到水,也就是可以看成木桶的边缘,先把木桶的边缘都放进优先队列中,这时取出最小的柱子,向这个柱子的 4 个方向扩散,扩散出的柱子有两种情况,如果比当前柱子大,那么不能接水,如果比当前柱子小,那么接到的水就是当前柱子高度减去扩散柱子的高度(为什么?因为当前柱子一定是边缘最小的了,所以它一定能接到水),后面在把扩散的柱子加入到优先队列中,已经比较完的柱子就移出队列,这样就又形成了新的桶的边缘,并且水桶面积也在不断缩小(当然要记录走过的柱子,防止重复走),最终就会计算完成。

C语言编程题_3D接雨水,百科,IT_百科,IT_C语言和C++语言,c语言,算法,开发语言

  下面是用C语言实现的3D接雨水:文章来源地址https://www.toymoban.com/news/detail-857867.html

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

#define Cols            (6)
#define Rows            (3)

#define Status_ToDo     (0) // 待处理的。
#define Status_Done     (1) // 已处理的。
#define Status_Border   (2) // 作为木桶板。

int addRainWaterOfTBLR(int height[][Cols], int status[][Cols], int minBorderHeight, int row, int col);

void initStatus(int arr[][Cols]) {
    // // 注: 使用下面语句得到的rowCount为0, 因为arr作为形参的时候就会被当作一个指针。
    // int rowCount = sizeof(arr) / sizeof(arr[0]);
    for (int row = 0; row < Rows; row++) {
        for (int col = 0; col < Cols; col++) {
            if (0 == row || Rows-1 == row || 0 == col || Cols-1 == col) {
                arr[row][col] = Status_Border;
            } else {
                arr[row][col] = Status_ToDo;
            }
        }
    }
    // 去掉四个角。
    arr[0][0] = arr[0][Cols-1] = arr[Rows-1][0] = arr[Rows-1][Cols-1] = Status_Done;
}

void showStatus(int height[][Cols], int status[][Cols]) {
    printf("打印状态:\n");
    for (int row = 0; row < Rows; row++) {
        for (int col = 0; col < Cols; col++) {
            printf("%d(%d), ", height[row][col], status[row][col]);
        }
        printf("\n");
    }
}

void findPositionOfMinBorder(int height[][Cols], int status[][Cols], int result[2]) {
    // printf("findPositionOfMinBorder\n");
    result[0] = 0;
    result[1] = 0;
    for (int row = 0; row < Rows; row++) {
        for (int col = 0; col < Cols; col++) {
            if (Status_Border == status[row][col]
                && ((0 == result[0] && 0 == result[1]) || height[row][col] < height[result[0]][result[1]])
            ) {
                result[0] = row;
                result[1] = col;
            }
        }
    }
    printf("最小板的位置是(%d,%d)\n", result[0], result[1]);
}

void repairBorder(int status[][Cols]) {
    for (int row = 0; row < Rows; row++) {
        for (int col = 0; col < Cols; col++) {
            if (Status_Border == status[row][col]) {
                //上下左右都不是待处理的。
                if ((0 == row || (row > 0 && status[row-1][col] != Status_ToDo))
                    && (Rows-1 == row || (Rows-1 > row && status[row+1][col] != Status_ToDo))
                    && (0 == col || (col > 0 && status[row][col-1] != Status_ToDo))
                    && (Cols-1 == col || (Cols-1 > col && status[row][col+1] != Status_ToDo))
                ) {
                    status[row][col] = Status_Done;
                }
            }
        }
    }
}

int addRainWaterAtPosition(int height[][Cols], int status[][Cols], int minBorderHeight, int row, int col) {
    int result = 0;
    // printf("addRainWaterAtPosition(%d,%d)\n", row, col);
    if (height[row][col] <= minBorderHeight) {
        result += (minBorderHeight - height[row][col]);
        result += addRainWaterOfTBLR(height, status, minBorderHeight, row, col);
    } else {
        status[row][col] = Status_Border;
    }
    return result;
}

int addRainWaterOfTBLR(int height[][Cols], int status[][Cols], int minBorderHeight, int row, int col) {
    int result = 0;
    // printf("addRainWaterOfTBLR(%d,%d)\n", row, col);
    status[row][col] = Status_Done;
    if (row > 0 && Status_ToDo == status[row-1][col]) { // 上。
        result += addRainWaterAtPosition(height, status, minBorderHeight, row-1, col);
    }
    if (row < Rows-1 && Status_ToDo == status[row+1][col]) { // 下。
        result += addRainWaterAtPosition(height, status, minBorderHeight, row+1, col);
    }
    if (col > 0 && Status_ToDo == status[row][col-1]) { // 左。
        result += addRainWaterAtPosition(height, status, minBorderHeight, row, col-1);
    }
    if (col < Cols-1 && Status_ToDo == status[row][col+1]) { // 右。
        result += addRainWaterAtPosition(height, status, minBorderHeight, row, col+1);
    }
    return result;
}

// 判断完成。
int checkFinish(int status[][Cols]) {
    for (int row = 0; row < Rows; row++) {
        for (int col = 0; col < Cols; col++) {
            if (Status_ToDo == status[row][col]) {
                return 0;
            }
        }
    }
    return 1;
}

// 简介:  3D接雨水。
int main(void)
{
    int rainWater = 0;
    int heightMap[][Cols] = {{1,4,3,1,3,2},{3,2,1,3,2,4},{2,3,3,2,3,1}};
    // printf("heightMap_rowCount = %d。\n", sizeof(heightMap) / sizeof(heightMap[0]));
    int (*status)[Cols] = malloc(sizeof(int) * (sizeof(heightMap) / sizeof(heightMap[0])) * Cols);
    initStatus(status);
    showStatus(heightMap, status);

    while(!checkFinish(status)) {
        int positionOfMinBorder[2] = {0, 0};
        findPositionOfMinBorder(heightMap, status, positionOfMinBorder);
        int minBorderHeight = heightMap[positionOfMinBorder[0]][positionOfMinBorder[1]];
        // printf("minBorderHeight=%d\n", minBorderHeight);
        rainWater += addRainWaterOfTBLR(heightMap, status, minBorderHeight, positionOfMinBorder[0], positionOfMinBorder[1]);
        repairBorder(status);
        showStatus(heightMap, status);
    }
    printf("总的接雨水量为%d\n", rainWater);

    free(status);

    printf("程序正常退出。\n");
    return 0;
}

到了这里,关于C语言编程题_3D接雨水的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 编程语言比拼之Java VS C++

    学Java还是C++?   Java和C++都是非常受欢迎的编程语言,各有各的优势和适用场景。以下是对它们的简要比较: 性能:C++通常被认为是一种更高效的编程语言,适用于对性能要求较高的应用程序,如游戏开发、嵌入式系统和高频交易等。C++具有更接近底层的控制能力,允许开发

    2024年02月13日
    浏览(43)
  • C++ 编程入门指南:深入了解 C++ 语言及其应用领域

    C++ 是一种跨平台的编程语言,可用于创建高性能应用程序。 C++ 是由 Bjarne Stroustrup 开发的,作为 C 语言的扩展。 C++ 为程序员提供了对系统资源和内存的高级控制。 该语言在 2011 年、2014 年、2017 年和 2020 年进行了 4 次重大更新,分别为 C++11、C++14、C++17 和 C++20。 C++ 是世界上

    2024年03月21日
    浏览(51)
  • [编程语言][C++][Qt]单独添加UI文件

    不知什么原因,Qt Creator并不是很完美很智能。当先写好界面类的头文件和源代码文件后,我们再添加用于可视化界面设计的UI文件时,会出现一些问题。 当使用CMake管理项目时,CMake会读取 CMakeLists.txt 文件来确定各种项目设置。需要把 MainWindow.ui 包含进项目时,在 CMakeLists.

    2024年02月07日
    浏览(46)
  • 最短路径算法的编程与实现 C语言

    1.掌握最短路径算法的基本原理及编程实现; operating system version:Win11 CPU instruction set:  x64 Integrated Development Environment:Viusal Studio 2022 1)建立一张图,选择一种存储结构(邻接矩阵或邻接表)初始化该图; 2)用Dijkstra算法实现点与点之间的最短路径。 1) 实现图的两种表示方法;

    2024年02月11日
    浏览(45)
  • 掌握Go语言:Go语言递归函数,解密编程之谜,探索算法的奥秘!(27)

    递归函数是指在函数内部调用自身的函数。在Go语言中,递归函数使用起来非常方便,但需要注意递归的终止条件,以避免无限循环。 Go语言递归函数的使用方法 在Go语言中,编写递归函数的基本步骤如下: 上述三点内容详细解释如下: 定义一个函数,函数内部调用自身 :

    2024年04月15日
    浏览(55)
  • Ubuntu22.2下C语言编程实现,首次,最佳适应算法

    编写C语言程序,模拟实现首次/最佳/最坏适应算法(选择其中之一即可)的内存块分配和回收,要求每次分配和回收后显示出空闲分区和已分配分区的情况。假设初始状态下,可用的内存空间为640KB。 假设下列作业请求序列: (1)作业1 申请130 KB (2)作业2 申请60 KB (3)作业

    2024年02月05日
    浏览(45)
  • 【C语言】C语言编程实战:Base64编解码算法从理论到实现(附完整代码)

    🧑 作者简介 :阿里巴巴嵌入式技术专家,深耕嵌入式+人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍 :分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导、简历面试辅导、技术架构设计优化、开发外包等服

    2024年03月13日
    浏览(39)
  • 【C/C++】C语言开发者必读:迈向C++的高效编程之旅

    🧑 作者简介 :阿里巴巴嵌入式技术专家,深耕嵌入式+人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍 :分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导、简历面试辅导、技术架构设计优化、开发外包等

    2024年03月20日
    浏览(50)
  • 算法初阶双指针+C语言期末考试之编程题加强训练

    常⻅的双指针有两种形式,⼀种是对撞指针,⼀种是左右指针。 对撞指针:⼀般⽤于顺序结构中,也称左右指针。 • 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼 近。 • 对撞指针的终⽌条件⼀般是两个指针相遇或者错开(

    2024年02月05日
    浏览(53)
  • 编程语言:微软 Azure CTO 表示,是时候停止在新项目中使用 C 和 C++

    Azure CTO Mark Russinovich 说,业界应该将 C 和 C++ 语言视为“已弃用”。 Windows 11 22H2:如何获得微软最新的操作系统更新以及接下来会发生什么 Microsoft Azure 的首席技术官 Mark Russinovich 表示,出于安全性和可靠性的考虑,开发人员应避免在新项目中使用 C 或 C++ 编程语言,而应使用

    2024年02月06日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包