包裹与数 —— multiset练习题
题目描述
有一个用于装整数的包裹,一开始包裹中没有数,接下来有 \(n\) 步操作,每一步操作包含三种类型:
1 x
:将一个整数 \(x\) 放入包裹;2 x
:从包裹中取出一个值为 \(x\) 的数(保证包裹中有值为 \(x\) 的数);3
:询问包裹中的所有数中最接近的一对数(即差的绝对值最小的两个数),并输出这对数的差的绝对值。
对于每次查询操作,输出对应的结果。如果查询时包裹中整数个数小于 \(2\) 个,输出 \(2147483647\)。
输入格式
输入的第一行包含一个整数 \(n(1 \le n \le 1000)\)。
接下来包含 \(n\) 行,每一行可能是 1 x
、2 x
、3
这三种操作中的一种。
输出格式
对于每一步查询操作,输出一行,为其对应的结果 —— 包裹中的所有数中最接近的一对数的差的绝对值。如果查询时包裹中整数个数小于 \(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;
}