• 20181030NOIP模拟赛T2


    WYT的刷子

    WYT有一把巨大的刷子,刷子的宽度为M米,现在WYT要使用这把大刷子去粉刷有N列的栅栏(每列宽度都为1米;每列的高度单位也为米,由输入数据给出)。

    使用刷子的规则是:

    1.与地面垂直,从栅栏的底部向上刷

    2.每次刷的宽度为M米(当剩余栅栏宽度不够M米的话,刷子也可以使用,具体看样例2)

    3.对于连续的M列栅栏,刷子从底向上,刷到的高度只能到这M列栅栏的最低高度。

    WYT请你回答两个问题:

    1、最少有多少个单位面积不能刷到(单位面积为1平米)

    2、在满足第一问的条件下,最少刷几次?

    输入

    共两行:

    第一行两个整数N和M。

    第二行共N个整数,表示N列栅栏的高度

    输出

    一行,两个整数,分别为最少剩余的单位面积数量和最少刷的次数。

    Input1:

    5 3

    5 3 4 4 5

    Output1:

    3

    2

    Input2:

    10 3

    3 3 3 3 3 3 3 3 3 3

    Output2:

    0

    4

    Input3:

    7 4

    1 2 3 4 3

    Output3:

    4

    4

    样例1的解释:

     

    高度分别为       5     3    4     4     5

    如上:

    黄色的方块表示共有3个单位面积没刷上

    绿色的框和红色的框表示一共刷了两次。

    数据范围:

    30%的数据:N<=10^3

    50%的数据:N<=10^5

    100%的数据:1<=N<=10^6, 1<=M<=10^6,N>=M, 每列栅栏的高度<=10^6.

    思路:

    单调栈裸题

    利用和求最大子矩形一样的方法,我们可以用单调栈求出每个高度它对应的区间

    如果这个区间小于m,则显然刷不到这个点的最高处

    然后我们O(N)的扫三遍

    第一遍判出哪些地方一定到不了最高点

    第二遍和第三遍求出这些到达不了最高点的地方能达到多高

    然后再O(n)扫一遍

    就能得到有多少个涂不了色的了

    至于涂得次数,贪心就好了

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define rii register int i
    #define rij register int j
    using namespace std;
    int n,m,zl[1000005],r[1000005],l[1000005];
    long long sum;
    int sta[1000005],top,sj[1000005],bj[1000005];
    inline int rd(){
        register int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    int main()
    {
        freopen("wyt.in","r",stdin);
        freopen("wyt.out","w",stdout);
        n=rd(),m=rd();
        for(rii=1;i<=n;i++)
        {
            zl[i]=rd();
            sum+=zl[i];
        }
        for(rii=1;i<=n;i++)
        {
            if(top==0)
            {
                top++;
                sta[top]=i;
                continue;
            }
            while(zl[sta[top]]>zl[i])
            {
                r[sta[top]]=i-1;
                top--;
            }
            top++;
            sta[top]=i;
        }
        while(top!=0)
        {
            r[sta[top]]=n;
            top--;
        }
        for(rii=n;i>=1;i--)
        {
            if(top==0)
            {
                top++;
                sta[top]=i;
                continue;
            }
            while(zl[sta[top]]>zl[i])
            {
                l[sta[top]]=i+1;
                top--;
            }
            top++;
            sta[top]=i;
        }
        while(top!=0)
        {
            l[sta[top]]=1;
            top--;
        }
        for(rii=1;i<=n;i++)
        {
            if(r[i]-l[i]+1<m)
            {
                bj[i]=1;
            }
        }
        for(rii=1;i<=n;i++)
        {
            if(bj[i]==1)
            {
                sj[i]=sj[i-1];
            }
            else
            {
                sj[i]=zl[i];
            }
        }
        for(rii=n;i>=1;i--)
        {
            if(bj[i]==1)
            {
                sj[i]=max(sj[i+1],sj[i]);
            }
        }
        for(rii=1;i<=n;i++)
        {
            sum-=sj[i];
        }
        cout<<sum<<endl;
        int ans=0;
        int val=sj[1],l=1;
        for(rii=2;i<=n;i++)
        {
            if(sj[i]!=val)
            {
                int sl=(i-l)/m;
                if(sl*m<(i-l))
                {
                    sl++;
                }
                ans+=sl;
                l=i;
                val=sj[i];
            }
        }
        int sl=(n-l+1)/m;
        if(sl*m<(n-l+1))
        {
            sl++;
        }
        ans+=sl;
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    OpenCV——IplImage
    OpenCV——常用函数查询
    OpenCV——Sobel和拉普拉斯变换
    OpenCV——CvSeq动态结构序列
    OpenCV——人脸检测
    Java—Integer类
    Java—NumberFormat与DecimalFormat类
    sql事务机制
    存储过程
    java中的抽象类和接口
  • 原文地址:https://www.cnblogs.com/ztz11/p/9877669.html
Copyright © 2020-2023  润新知