• GDUT 积木积水 2*n 时间复杂度


    题意

    Description

    现有一堆边长为1的已经放置好的积木,小明(对的,你没看错,的确是陪伴我们成长的那个小明)想知道当下雨天来时会有多少积水。小明又是如此地喜欢二次元,于是他把这个三维的现实问题简化成二维的问题。设雨量无穷、积木不透水、积木间无缝连接,问在这个二次元的世界里,已放置好的积木会有多少单位的积水量? 
    这里写图片描述

    Input

    第一行包含一个整数T(T≤100),表示接下来的测试样例个数。 每个测试样例有两行组成: 第一行包含一个整数N(N≤1e6),表示积木的列数; 第二行包含N个整数Ai(Ai≤1e6),表示第i列积木的个数。

    Output

    每个样例输出一行,包含一个整数,为题目所求。

    Sample Input


    11 
    6 2 2 4 2 0 3 4 4 5 1

    Sample Output

    19



    思路:

      从两边开始找能够储存水的地方  从两边开始选择一个比较矮的,往中间找找到比自己高的,计算此时存的水量,然后依次循环。

    #include <iostream>
    #include<stdio.h>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<stdlib.h>
    #include<map>
    
    using namespace std;
    const int INF=(1<<31)-1;
    typedef long long int LL;
    LL a[1000010];
    LL sum[1000010];
    int main()
    {
        int n_case;
        scanf("%d",&n_case);
        while(n_case--)
        {
            LL n,i,j;
            LL ans=0;
            memset(a,0,sizeof(a));
            scanf("%lld",&n);
            a[0]=-1;
            a[n+1]=-1;
            sum[0]=0;
            for(i=1; i<=n; i++)
            {
                scanf("%lld",&a[i]);
                sum[i]=a[i]+sum[i-1];// sum 表示从第一个开始到i  积木所占的体积;
            }
            LL left=1,right=n;
            while(left<right)  //往中间找, 找到比自己高的  计算体积  ,并且更新左右标记点,直到相遇
            {
                if(a[left] <= a[right])  //以矮的边开始找
                {
                    for(i=left+1; i<=right; i++)
                    {
                        if(a[i]>=a[left]) break;
                    }
                    ans=ans+min(a[left],a[i])*(i-left-1)-(sum[i-1]-sum[left]);  //计算此时体积
                    left=i;
                }
                else
                {
                    for(i=right-1; i>=left; i--)
                    {
                        if(a[i]>=a[right]) break;
                    }
                    ans=ans+min(a[right],a[i])*(right-i-1)-(sum[right-1]-sum[i]);
                    right=i;
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    ArrayList用法
    Delegate比较全面的例子(原创)
    一个登陆页面,包含了初始化用户,输入检测,错误处理等
    C#线程 在某一时间内,只有N个线程在并发执行,其余都在队列中的实现
    ASP.Net防止刷新自动触发事件的解决方案
    存储过程编写经验和优化措施 (转)
    [转]数据库开发21条军规
    [转]Ajax简单客户登陆验证
    用SqlBulkCopy进行大批量数据迁移
    什么时候使用哪个数据绑定控件(asp.net)
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7208008.html
Copyright © 2020-2023  润新知