c语言做接雨水问题的


int trap(int* height, int heightSize){
    if(heightSize==1)
    return 0;
    int i,j,k;
    int res=0;
    for(i=0;i<heightSize-1;i++){
        for(j=i+1;j<heightSize;j++){
            if(height[j]>=height[i]){
                for(k=i+1;k<j;k++){
                    res+=(height[i]-height[k]);
                }
                i=j;
                break;
            }
        }
    }
    if(height[0]<height[1]){
        res=res-(height[1]-height[0]);
    }
    return res;
}

为什么这样是错的,题目如下

img

你代码我运行了结果不对

#include <iostream>

using namespace std;
 
int trap(int* height, int heightSize){
    if(heightSize==1)
    return 0;
    int i,j,k;
    int res=0;
    for(i=0;i<heightSize-1;i++){
        for(j=i+1;j<heightSize;j++){
            if(height[j]>=height[i]){
                for(k=i+1;k<j;k++){
                    res+=(height[i]-height[k]);
                }
                i=j;
                break;
            }
        }
    }
    if(height[0]<height[1]){
        res=res-(height[1]-height[0]);
    }
    return res;
}
int main()
{
    int height[] = { 0,1,0,2,1,0,1,3,2,1,2,1 };
    int r = trap(height, 12);
    cout << r;
    return 0;
}

你的代码返回1

我写了一个,效率未必高,但是应该是对的

#include <iostream>

using namespace std;
 
int trap(int* height, int heightSize){
    int res = 0;
    int add;
    while (1)
    {
        add = 0;
        for (int i = 1; i < heightSize - 1; i++)
        {
            int curr = height[i] + 1;
            int bleft = 0;
            int bright = 0;
            for (int j = i - 1; j >= 0; j--)
            {
                if (height[j] >= curr) { bleft = 1; break; }
            }
            for (int j = i + 1; j < heightSize; j++)
            {
                if (height[j] >= curr) { bright = 1; break; }
            }
            if (bleft && bright)
            {
                height[i]++;
                add++;
            }
        }
        res += add;
        if (add == 0) break;
    }
    return res;
}
int main()
{
    int height[] = { 0,1,0,2,1,0,1,3,2,1,2,1 };
    int r = trap(height, 12);
    cout << r;
    return 0;
}

img

供参考:https://blog.csdn.net/MarlboroLRX/article/details/120810325

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7806181
  • 这篇博客你也可以参考下:c语言如何实现喝汽水问题
  • 除此之外, 这篇博客: C语言实现接雨水问题中的 描述 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个柱子高度图,计算按此排列的柱子,下雨之后能接多少雨水。

    输入:[3,1,2,5,2,4]

    返回值:5

    说明:数组 [3,1,2,5,2,4] 表示柱子高度图,在这种情况下,可以接 5个单位的雨水,蓝色的为雨水

     

    接雨水问题_牛客题霸_牛客网 (nowcoder.com)

    解释:

    设置两个水量,一个临时水量,一个最终水量;两个下标啊a,b,

    a指向开始出不动,b指向开始出加一往右移动;b下标对应的值如果比a下标对应的值小,作差,拿个临时值接收;当b下标遇到比a下标的值大时,就将b赋值a,把临时水量赋值最终水量;

    如果到最后还没有遇到比a大的值,那就说明此时的a下标对应的值与后面相比是最大值,反过来把尾座标当做开始,a对应的对标作为终点,然后把求得的水量相加到最终水量 ;

    下面用C语言实现:

    long long maxWater(int* arr, int arrLen ) {
        // write code here
        long long water=0,ret=0;
        int a=0,b=1,c=arrLen-1;
        while(b<=c)
        {
            if(arr[b]<arr[a])
            {
                ret+=arr[a]-arr[b];//作差
            }
            else
            {
                water+=ret;
                ret=0;
                a=b;
            }
            b++;
        }
        if(ret!=0)//只要临时水量有水就说明最后没找到比a下标对应的值大的
        {
            b=c-1;
            while(b>a)
            {
                if(arr[b]<arr[c])
                {
                    water=water+arr[c]-arr[b];
                    //因为知道了终点是a对应下标的地方,所以不需要临时水量
                }
                else
                {
                    c=b;
                }
                b--;//此时是往左走
            }
        }
        return water;
    }

  • 您还可以看一下 陈虎老师的一小时快速学习屏幕录像和视频编辑实战教程课程中的 如何给视频添加水印小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    问题分析: 这段代码的目标是计算给定数组中能够接住雨水的总量。它使用两个辅助数组left[]right[]来记录每个位置左边和右边的最大值。然后在遍历原始数组时,计算当前位置所能接住的雨水量。最后返回总的雨水量。

    根据代码的逻辑分析,问题可能出在如何计算“左边最大值”和“右边最大值”的部分。这段代码使用的方法是先遍历一次原始数组找到每个位置的左边最大值,然后再遍历一次找到每个位置的右边最大值。然而,这种方法在计算右边最大值的时候,使用了一个初始化为最后一个元素的变量maxSeenSoFar来记录当前最大值。这样,在计算右边最大值时会跳过最后一个元素,因为它的右边没有更大的元素。

    解决方案: 我们可以对代码进行改进,在计算右边最大值时,从倒数第二个元素开始遍历到第一个元素,并使用另一个变量rightMax来记录当前位置右边的最大值。同时,我们可以将左边最大值和右边最大值的计算合并到一个循环中。这样,我们只需遍历一次原始数组即可完成计算。

    以下是改进后的代码:

    #include <stdio.h>
    
    int trapRainwater(int arr[], int size) {
        if (size <= 2) {
            return 0;
        }
    
        int left[size], right[size];
        left[0] = arr[0];
    
        int maxSeenSoFar = arr[0];
        for (int i = 1; i < size; i++) {
            if (arr[i] > maxSeenSoFar) {
                maxSeenSoFar = arr[i];
            }
            left[i] = maxSeenSoFar;
        }
    
        right[size - 1] = arr[size - 1];
        int rightMax = arr[size - 1];
        int totalWater = 0;
    
        for (int i = size - 2; i >= 1; i--) {
            if (arr[i] > rightMax) {
                rightMax = arr[i];
            }
            right[i] = rightMax;
    
            int minHeight = left[i] < right[i] ? left[i] : right[i];
            int water = minHeight - arr[i];
            totalWater += water;
        }
    
        return totalWater;
    }
    
    int main() {
        int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
        int arrSize = sizeof(arr) / sizeof(arr[0]);
    
        int result = trapRainwater(arr, arrSize);
        printf("The amount of trapped rainwater is: %d\n", result);
    
        return 0;
    }
    

    现在运行这段代码,应该可以得到正确的结果。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^