C语言编程题_3D接雨水

news/2024/5/18 23:29:46

接雨水的题目描述如下。

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

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

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

  问题描述

  难度:困难

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

  示例1:

  输入: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接雨水:

#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;
}


http://www.mrgr.cn/p/30364852

相关文章

JMeter定时器(一)

一 前言 环境: window 10 JMeter 5.3 二 定时器 定时器(Timers)的作用就是对取样器(sampler)的执行进行延迟,所以,定时器只对同作用域的取样器有意义 定时器会在其所处作用域内的取样器之前执行。把定时器添加为取样器的子节点,这样就会在取样器之前执行 1 固定定时器…

SpringCloud-AMQP

【BV1LQ4y127n4】SpringAMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,使用起来非常方便。 SpringAmqp官方地址:https://spring.io/projects/spring-amqpSpringAMQP提供了三个功能:自动声明队列、交换机及其绑定关系 基于注解的监听器模式,异…

Pandas read_csv 参数详解

前言 在使用 Pandas 进行数据分析和处理时,read_csv 是一个非常常用的函数,用于从 CSV 文件中读取数据并将其转换成 DataFrame 对象。read_csv 函数具有多个参数,可以根据不同的需求进行灵活的配置。本文将详细介绍 read_csv 函数的各个参数及其用法,帮助大家更好地理解和利…

倒计时开始!Big Demo Day第十二期,揭秘DePIN,探索Web3未来(附参会指南)

香港—— 全球领先的 Web3.0 活动 Big Demo Day 第十二期即将于 4 月 26 日在香港数码港盛大举行。本次活动由知名科技企业 ZeeprLabs 赞助&#xff0c;Central Research 主办&#xff0c;并得到 Techub News 的联合主办以及数码港、852Web3 等机构的合作支持。 在过去的 11 期…

【Hadoop】-HDFS的Shell操作[3]

目录 前言 一、HDFS集群启停命令 1.一键启停脚本可用 2.独立进程启停可用 二、文件系统操作命令 1、创建文件夹 2、查看指定目录下内容 3、上传文件到HDFS指定目录下 4、查看HDFS文件内容 5、下载HDFS文件 6、拷贝HDFS文件 7、追加数据到HDFS文件中 8、HDFS数据移…

(数据科学学习手札160)使用miniforge代替miniconda

本文已收录至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes1 简介大家好我是费老师,conda作为Python数据科学领域的常用软件,是对Python环境及相关依赖进行管理的经典工具,通常集成在anaconda或miniconda等产品中供用户日常使用。但长久以来,conda在很…

uniapp:小白1分钟学会使用webSocket(可无脑复制)

uni.connectSocket() uni.$emit页面通信 项目中使用uni.connectSocket()创建webSocket的总结&#xff0c;代码可无脑复制&#xff0c;直接使用。 1、main.js 引入vuex import store from ./store; Vue.prototype.$store store;vuex中封装webSocket 2、vuex的&#xff1a;index…

第十五届蓝桥杯省赛第二场C/C++B组G题【最强小队】题解

20pts 枚举所有可能的左端点、右端点&#xff0c;时间复杂度 O ( n 2 ) O(n^2) O(n2)。 对于每个区间进行遍历检测&#xff0c;时间复杂度 O ( n 3 ) O(n^3) O(n3)。 100pts 由于数据范围为 1 0 5 10^5 105&#xff0c;所以肯定只能进行一次枚举。 我们尝试枚举右端点&…

【第3节】“茴香豆“:搭建你的 RAG 智能助理

目录 1 基础知识1.1.RAG技术的概述1.2 RAG的基本结构有哪些呢&#xff1f;1.3 RAG 工作原理&#xff1a;1.4 向量数据库(Vector-DB )&#xff1a;1.5 RAG常见优化方法1.6RAG技术vs微调技术 2、茴香豆介绍2.1应用场景2.2 场景难点2.3 茴香豆的构建&#xff1a; 3 论文快读 1 基础…

前端框架技术调研

目前程序员使用前端框架最多的是哪一个&#xff1f;

[Flutter3] 记录Dio的简单封装(一)

文章目录 效果使用ResponseEntity类DioManager封装_onResponse / _onDioException 的设计Response的处理catch处理 效果 请求成功/失败/异常的日志输出效果 成功: 失败:500 失败:404 网络异常: 使用 举个使用的例子, 在调用 DioManager的时候, 直接通过返回值的状态, 来…

jenkins修改全局安全配置之后登录错误

教训&#xff08;流泪&#xff09; 事情是这样的&#xff0c;第一次我需要用单点登录集成jenkins&#xff0c;jenkins可以通过插件的方式支持cas协议&#xff0c;我当时也不很懂&#xff0c;经过我学网上的一顿乱配置&#xff0c;jenkis上不去了&#xff0c;虽然这是公司本地环…

常见Bug和问题定位

依赖冲突导致的问题定位 主要流程 现象: 项目提示某个依赖的方法不存在, 通过点击源码发现是存在的, 可能是依赖冲突导致的 猜测: 即使IDEA点击进去是一个版本,但是可能实际中打包编译的使用的是另一个版本导致找不到源码的对应方法 解决思路: 查看对应的日志提示看具体是…

Caused by: java.lang.ClassNotFoundException: org.junit.runner.manipulation.Filter问题的解决

问题描述问题解决 后来经过查阅资料发现,是这里出现了问题:只需要将JUnit的路径更改到classpath下面就可以啦:问题完美解决!

games101-3 BRDF101

BRDF101 概述 本文基于知乎Maple对brdf的文章,在此基础又收集了一些其它来源的关于brdf的文章,希望能够完全理解记忆相关知识 关于Jakub Boksansky的文章,看的过程中又去搜集了很多其它文章来理解,发现已经超出了我目前的知识厚度,因此只会简单的翻译一下我能理解的部分,…

开源相机管理库Aravis例程学习(四)——multiple-acquisition-signal

本文针对Aravis官方例程中的:02-multiple-acquisition-signal做简单的讲解,并介绍其中部分函数目录简介例程代码函数说明g_main_loop_newg_main_loop_rung_main_loop_quitg_signal_connectarv_stream_set_emit_signalsQ&A回调函数的同步调用与异步调用帧丢失问题 简介 本…

Redis:报错Creating Server TCP listening socket *:6379: bind: No error

错误&#xff1a; window下启动redis服务报错&#xff1a; Creating Server TCP listening socket *:6379: bind: No error 原因&#xff1a; 端口6379已被绑定&#xff0c;应该是因为上次未关闭服务 解决&#xff1a; ①依次输入命令&#xff1a; redis-cli.exe &#xff08…

机器学习-期末复习

本文的内容按照作者的课程考试要求书写&#xff0c;仅供复习参考。&#x1f337;&#x1f337;&#x1f337;欢迎大家指正&#xff01; 机器学习是一种人工智能&#xff08;AI&#xff09;的分支领域&#xff0c;它致力于开发能够通过数据学习和改进的算法和模型。简而言之&…

openCV 图像清晰度检测

图像清晰度评价算法有很多种,在空域中,主要思路是考察图像的领域对比度,即相邻像素间的灰度特征的梯度差;在频域中,主要思路是考察图像的频率分量,对焦清晰的图像高频分量较多,对焦模糊的图像低频分量较多。 这里实现3种清晰度评价方法,分别是Tenengrad梯度方法、Lapla…