Hrbust-2352 Save the Little Ant

本文介绍了一种计算二维地形图中积水体积的高效算法。通过寻找最高点作为边界,并分别从两侧扫描,实现O(n)时间复杂度。算法适用于解决凹形地形的积水问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述

1e5的数据量,一开始想的一层一层遍历高度作差肯定会超时,只能做线性的O(n)扫描。
因此这么想,要算积水,那么肯定有左右两个边界使其成为“凹”型,那么复杂的情况是,这个“凹”型不好找,如何确定整个图形的边界位置,可能凹中带凹,可能几个坑是分开的。这样一来就会不止扫一次才能找到这样图形。
于是,我们可以找到整个图形中的最高点作为图形的分界线,将其分为左右两部分,分开各扫一遍,这样只需O(n)的复杂度。
计算水体积时,从一边向中间扫,找到较大值时,将其记录,找到比记录的值小的值时,与记录的值作差即可得到这个“凹”处的体积。因为有了中央最高处作坑的其中一个固定边界,这样只需要遍历找到另一个边界,即可得到低处与较高处的差值。因为是由内而外的遍历,这样先找到的较大值就会围住比较大值小的低处。必定形成坑。左右遍历后得到的差值之和便是总的积水体积。

#include<stdio.h>
int main()
{
    int a[100005],n;
    while(scanf("%d",&n)!=EOF)
    {
        long long Max=0,maxi=0,ans=0;///坑点,地平线是0,所以负数都是坑,不管边缘(第一个和最后一个数)是谁都算凹下去的
        for(int i=0; i<n; i++)///最坏情况是2e5*1e5,要用long long
        {
            scanf("%d",&a[i]);
            if(a[i]<0)ans+=-a[i],a[i]=0;///找到一个序列中最大值的位置,然后左右向这个最大值的位置扫
            if(a[i]>Max)///每次更新左右扫进去的最大值,如果大于最大值,更新最大值,否则减去,算坑,这样就把其中一个边界都作为最大值,另一个左右的边界是会更新变化的最大值
            {
                Max=a[i];
                maxi=i;
            }
        }///整个序列的最大值不在计算范围内,因为他作为了边界
        int maxx=0;
        for(int i=0; i<maxi; i++)
            if(a[i]>maxx)maxx=a[i];
            else ans+=maxx-a[i];
        maxx=0;
        for(int i=n-1; i>maxi; i--)
            if(a[i]>maxx)maxx=a[i];
            else ans+=maxx-a[i];
        printf("%lld\n",ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值