• 矩形切割


    有一个w*h的矩形,每次对它横着切一刀,或者竖着切一刀,每一刀切完之后,有若干个矩形会被分成两个更小的矩形。每一刀切完之后,请找出所有矩形中面积最大的。

    输入

    第一行是三个整数w h n表示矩形的宽度和高度,以及操作的数量

    接下来n行每行一个操作

    是下列两种形式之一:

    H y (表示横着在离矩形下边界y的位置切一刀)

    V x(表示竖着在离矩形左边界x的位置切一刀)

    2 \le w, h \le 200000, 1 \le n \le 2000002 w,h 200000,1 n 200000

    1 ≤ y ≤ h - 1,1 ≤ x ≤ w - 1

    输出

    每次操作之后输出一行,表示当前最大矩形的面积。

    样例

    输入

    复制
    4 3 4
    H 2
    V 2
    V 3
    V 1

    输出

    复制
    8
    4
    4
    2

    输入

    复制
    7 6 5
    H 4
    V 3
    V 5
    H 2
    V 1

    输出

    复制
    28
    16
    12
    6
    4

    提示

    子任务1,20分,1 \le n \le 1001 n 100

    子任务2,80分,全范围

    横着切和竖着切互不影响,我们每次只需要找出最大的宽和最大的高相乘就可以了,可以用优先队列,但是对于被切割的块又不能准确定位,可以用set记录切刀的位置,当队列头部被切割过时再进行更新。

    #pragma warning(disable:4996)
    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <set>
    #include <algorithm>
    #include <functional>
    #define inf 0x3f3f3f3f
    int main()
    {
        int w, h, n;
        char op[2];
        int d;
        std::priority_queue < std::pair<int, int>, std::vector<std::pair<int, int>>, std::less<std::pair<int, int>>> qr, qc;
        scanf("%d%d%d", &w, &h, &n);
        qr.push(std::make_pair(h, 0));
        qc.push(std::make_pair(w, 0));
        std::set<int> cutR, cutC;
        cutR.insert(0);
        cutR.insert(h);
        cutC.insert(0);
        cutC.insert(w);
        for (int i = 0; i < n; i++)
        {
            scanf("%s%d", op, &d);
            if (op[0] == 'V')
            {
                cutC.insert(d);
            }
            else
            {
                cutR.insert(d);
            }
            bool flag = true;
            while (flag)
            {
                int l = qr.top().second;
                int r = l + qr.top().first;
                std::set<int>::iterator it = cutR.lower_bound(l);
                while (*it != r)
                {
                    if (*it != l)
                    {
                        qr.push(std::make_pair(*it - l, l));
                        l = *it;
                    }
                    it++;
                }
                if (l != qr.top().second)
                {
                    qr.push(std::make_pair(*it - l, l));
                    qr.pop();
                }
                else
                {
                    flag = false;
                }
            }
            flag = true;
            while (flag)
            {
                int l = qc.top().second;
                int r = l + qc.top().first;
                std::set<int>::iterator it = cutC.lower_bound(l);
                while (*it != r)
                {
                    if (*it != l)
                    {
                        qc.push(std::make_pair(*it - l, l));
                        l = *it;
                    }
                    it++;
                }
                if (l != qc.top().second)
                {
                    qc.push(std::make_pair(*it - l, l));
                    qc.pop();
                }
                else
                {
                    flag = false;
                }
            }
            printf("%lld\n", (long long)qr.top().first * qc.top().first);
        }
        return 0;
    }
    如果觉得有帮助,点个推荐啦~
  • 相关阅读:
    ctrl+shift+k取消
    ERROR 1872
    swap
    mysql主从跳过错误
    undo
    gtid
    falcon监控指标
    连接数
    datetime与timestamp相互转换
    截取文件内容
  • 原文地址:https://www.cnblogs.com/8023spz/p/15515581.html
Copyright © 2020-2023  润新知