• 【洛谷 P5250】【深基17.例5】木材仓库 题解(集合+upper_bound)


    【深基17.例5】木材仓库

    题目描述

    博艾市有一个木材仓库,里面可以存储各种长度的木材,但是保证没有两个木材的长度是相同的。作为仓库负责人,你有时候会进货,有时候会出货,因此需要维护这个库存。有不超过 100000 条的操作:

    • 进货,格式1 Length:在仓库中放入一根长度为 Length(不超过 1 0 9 10^9 109) 的木材。如果已经有相同长度的木材那么输出Already Exist
    • 出货,格式2 Length:从仓库中取出长度为 Length 的木材。如果没有刚好长度的木材,取出仓库中存在的和要求长度最接近的木材。如果有多根木材符合要求,取出比较短的一根。输出取出的木材长度。如果仓库是空的,输出Empty

    输入格式

    输出格式

    样例 #1

    样例输入 #1

    7
    1 1
    1 5
    1 3
    2 3
    2 3
    2 3
    2 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    样例输出 #1

    3
    1
    5
    Empty
    
    • 1
    • 2
    • 3
    • 4

    思路

    使用一个 set 类型的容器 s,用来存储木材仓库中已有的木材长度。在插入木材时,使用 set 的 insert 函数,如果插入失败说明该木材已经存在,输出 Already Exist。在取出木材时,首先判断 set 是否为空,如果为空则输出 Empty。然后使用 set 的 find 函数查找是否有该木材,如果有则直接输出该木材并删除;如果没有,则使用 set 的 upper_bound 函数找到第一个大于该木材长度的木材,分别计算其前一个和后一个木材与该木材的长度差,取最小值输出,并删除该木材。

    set 的 insert 方法返回一个 pair,其中第一个元素是一个迭代器,指向可能插入的元素,第二个元素是布尔值,如果该元素实际插入,则为true。若返回的是false,则直接输出 Already Exist。

    在取出元素时,注意处理特殊情况:

    1. ub在begin,set中所有数都比len大,直接输出最小的元素
    2. ub在end,set中所有数都比len小,直接输出最大的元素

    AC代码

    #include 
    #include 
    #define AUTHOR "HEX9CF"
    using namespace std;
    
    int n;
    set<int> s;
    
    int main()
    {
        s.clear();
        cin >> n;
        while (n--)
        {
            int op, len;
            cin >> op >> len;
            auto it = s.find(len);
            if (1 == op)
            {
                if (!s.insert(len).second)
                {
                    cout << "Already Exist" << endl;
                }
            }
            else
            {
                if (s.empty())
                {
                    cout << "Empty" << endl;
                    continue;
                }
                if (it == s.end())
                {
                    auto ub = s.upper_bound(len);
                    if (ub == s.begin())
                    {
                        // ub在begin,set中所有数都比len大
                        cout << *ub << endl;
                        s.erase(ub);
                        continue;
                    }
                    else if (ub == s.end())
                    {
                        // ub在end,set中所有数都比len小
                        ub--;
                        cout << *ub << endl;
                        s.erase(ub);
                        continue;
                    }
                    auto it2 = ub;
                    auto it1 = it2;
                    it1--;
                    if (len - *it1 <= *it2 - len)
                    {
                        cout << *it1 << endl;
                        s.erase(*it1);
                    }
                    else
                    {
                        cout << *it2 << endl;
                        s.erase(*it2);
                    }
                }
                else
                {
                    cout << *it << endl;
                    s.erase(it);
                }
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
  • 相关阅读:
    【预测模型-ELM分类】基于极限学习机ELM+OSELM+KELM+半监督SSELM+USELM实现数据集分类附matlab代码
    计算机毕业设计springboot+vue+elementUI校园疫情防控系统
    【计算机网络】——传输层
    golang redis lua脚本 和 lua function
    ERP生产作业控制
    一篇解决Elasticsearch全部问题。
    Pr怎么消除人声?三个方法解决!
    赶紧进来!!!教你C语言实现扫雷小游戏(文章最后有源码!!!)
    linux中使用arthas进行jvm内存分析
    powerbi从文本中提取想要的字段并分组
  • 原文地址:https://blog.csdn.net/qq_34988204/article/details/133518810