包裹与数 —— multiset练习题

题目描述

有一个用于装整数的包裹,一开始包裹中没有数,接下来有 (n) 步操作,每一步操作包含三种类型:

  • 1 x:将一个整数 (x) 放入包裹;
  • 2 x:从包裹中取出一个值为 (x) 的数(保证包裹中有值为 (x) 的数);
  • 3:询问包裹中的所有数中最接近的一对数(即差的绝对值最小的两个数),并输出这对数的差的绝对值。

对于每次查询操作,输出对应的结果。如果查询时包裹中整数个数小于 (2) 个,输出 (2147483647)

输入格式

输入的第一行包含一个整数 (n(1 le n le 1000))
接下来包含 (n) 行,每一行可能是 1 x2 x3 这三种操作中的一种。

输出格式

对于每一步查询操作,输出一行,为其对应的结果 —— 包裹中的所有数中最接近的一对数的差的绝对值。如果查询时包裹中整数个数小于 (2) 个,输出 (2147483647)

样例输入

9
1 2
1 5
3
1 7
3
2 5
3
2 7
3

样例输出

3
2
5
2147483647

说明/提示

样例解释:

  • (1) 步操作之后集合中的元素为 ({ 2 })
  • (2) 步操作之后集合中的元素为 ({ 2, 5 })
  • (3) 步操作时,集合中最接近的两个数是 (2)(5),它们的差为 (5-2=3)
  • (4) 步操作之后集合中的元素为 ({ 2, 5, 7 })
  • (5) 不操作时,集合中最接近的两个数是 (5)(7),它们的差为 (7-5=2)
  • (6) 步操作之后集合中的元素为 ({ 2, 7 })
  • (7) 步操作时,集合中最接近的两个数是 (2)(7),它们的差为 (7-2=5)
  • (8) 步操作之后集合中的元素为 ({ 2 })
  • (9) 不操作时,因为集合中只有一个元素,所以输出 (2147483647)

示例程序

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int n, op, x;
multiset<int> num_set, diff_set;
void add(int x) {
    multiset<int>::iterator it = num_set.lower_bound(x);
    int num1 = -1, num2 = -1;
    if (it != num_set.end()) {
        if (it != num_set.end()) num1 = *it;
        diff_set.insert(num1 - x);
    }
    if (it != num_set.begin()) {
        it --;
        num2 = *it;
        diff_set.insert(x - num2);
    }
    if (num1 != -1 && num2 != -1) {
        it = diff_set.lower_bound(num1 - num2);
        diff_set.erase(it);
    }
    num_set.insert(x);
}
void del(int x) {
    multiset<int>::iterator it = num_set.lower_bound(x), it2;
    assert(it != num_set.end() && (*it) == x);
    int num1 = -1, num2 = -1;
    it ++;
    if (it != num_set.end()) {
        num1 = *it;
        it2 = diff_set.lower_bound(num1 - x);
        diff_set.erase(it2);
    }
    it --;
    if (it != num_set.begin()) {
        it --;
        num2 = *it;
        it2 = diff_set.lower_bound(x - num2);
        diff_set.erase(it2);
        it ++;
    }
    if (num1 != -1 && num2 != -1) {
        diff_set.insert(num1 - num2);
    }
    num_set.erase(it);
}
int func_find() {
    int ans = INT_MAX;
    if (num_set.size() < 2) return ans;
    multiset<int>::iterator it = diff_set.begin();
    return *it;
}
int main() {
    cin >> n;
    while (n --) {
        cin >> op;
        if (op == 3) cout << func_find() << endl;
        else {
            cin >> x;
            if (op == 1) add(x);
            else del(x);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/quanjun/p/13934389.html