• WYT的刷子


    WYT的刷子

    题目描述

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

    使用刷子的规则是:

    1. 与地面垂直,从栅栏的底部向上刷
    2. 每次刷的宽度为M米(当剩余栅栏宽度不够M米的话,刷子也可以使用,具体看样例2)
    3. 对于连续的M列栅栏,刷子从底向上,刷到的高度只能到这M列栅栏的最低高度。

    WYT请你回答两个问题:

    1. 最少有多少个单位面积不能刷到(单位面积为1平米)
    2. 在满足第一问的条件下,最少刷几次?

    输入格式

    共两行:

    第一行两个整数N和M。

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

    输出格式

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

    样例

    样例输入1

    5 3
    5 3 4 4 5
    

    样例输出1

    3
    2
    

    样例输入2

    10 3
    3 3 3 3 3 3 3 3 3 3
    

    样例输出2

    0
    4
    

    样例输入3

    7 4
    1 2 3 4 3 2 1
    

    样例输出3

    4
    4
    

    样例1的解释:

    image

    高度分别为 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.

    code

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e6 + 10, INF = 0x3f3f3f3f;
    
    struct Node {
        int id;
        long long high;
    } sol[maxn], solmin[maxn], solmax[maxn];
    
    long long height[maxn], f[maxn];
    long long ans = 0;
    int flag = 1, t = 0;
    int n, m;
    void get_min() {
        for (int i = 1; i <= n; i++) {
            while (flag <= t && sol[t].high >= height[i]) t--;
            t++;
            sol[t].id = i;
            sol[t].high = height[i];
            if (i >= m) {
                if (sol[flag].id <= i - m)
                    flag++;
                solmin[i].high = sol[flag].high;
                solmin[i].id = sol[flag].id;
            }
        }
        for (int i = 1; i < m; i++) {
            solmin[i].id = i;
            solmin[i].high = -INF;
        }
    }
    
    void get_max() {
        flag = 1, t = 0;
        for (int i = 1; i <= n; i++) {
            while (flag <= t && solmax[t].high <= solmin[i].high) t--;
            solmax[++t].id = i;
            solmax[t].high = solmin[i].high;
            if (i >= m) {
                if (solmax[flag].id <= i - m)
                    flag++;
                f[i - m + 1] = solmax[flag].high;
                ans += height[i - m + 1] - f[i - m + 1];
            }
        }
        long long maxh = -INF;
        for (int i = n; i > n - m + 1; i--) {
            maxh = max(maxh, solmin[i].high);
            f[i] = maxh;
            ans = ans + height[i] - f[i];
        }
    }
    
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n; i++) cin >> height[i];
        get_min();
        get_max();
        int last = 1, num = 1;
        for (int i = 1; i <= n; i++) {
            if (i - last + 1 > m || f[last] != f[i]) {
                last = i;
                num++;
            }
        }
        cout << ans << endl << num << endl;
        return 0;
    }
    
  • 相关阅读:
    C++各大有名库的介绍——C++标准库
    转换中文数字成为阿拉伯数字
    nutch 写一个indexingfilter插件
    nutch从网页中提取字段并索引_HtmlParseFilter
    java csv操作类
    简单的有限状态机
    getResource()和getResourceAsStream的路径问题
    eclipse修改整个工作空间的编码
    批处理启动tomcat
    java linq
  • 原文地址:https://www.cnblogs.com/hellohhy/p/13221282.html
Copyright © 2020-2023  润新知