木材仓库
博艾市有一个木材仓库,里面可以存储各种长度的木材,但是保证没有两个木材的长度是相同的。作为仓库负责人,你有时候会进货,有时候会出货,因此需要维护这个库存。有不超过 100000 条的操作:
- 进货,格式
1 Length
:在仓库中放入一根长度为Length
(不超过 1 0 9 10^9 109 ) 的木材。如果已经有相同长度的木材那么输出Already Exist
。 - 出货,格式
2 Length
:从仓库中取出长度为Length
的木材。如果没有刚好长度的木材,取出仓库中存在的和要求长度最接近的木材。如果有多根木材符合要求,取出比较短的一根。输出取出的木材长度。如果仓库是空的,输出Empty
。
题目分析
此题考察的是set和lower_bound的使用,自己当时已经差不多忘记了有lower_bound这么一个东西
set里的几个方法在这里回顾一下
- s.erase(value) ,在直接在容器中删除值为value的元素
- lower_bound(value),查找出大于等于value的值的对应地址(指针)
#include <bits/stdc++.h>
using namespace std;
int main() {
int m;
scanf("%d", &m);
set<int> s;
while (m--) {
int op, l;
scanf("%d %d", &op, &l);
if (op == 1) {
int sz = s.size();
s.insert(l);
if (sz == s.size()) puts("Already Exist");
} else if (op == 2) {
if (s.size() == 0) { // 仓库为空
puts("Empty");
continue;
}
if (s.count(l)) { // 长度正好
cout << l << endl;
s.erase(l);
}
else { // 没有正好长度
auto it = s.lower_bound(l); //选出大于等于l的木材
int b = *it;
if (it != s.begin()) it--;
int a = *it;
if (abs(b-l) < abs(a-l)) {
cout << b << endl;
s.erase(b);
} else {
cout << a << endl;
s.erase(a);
}
}
}
}
return 0;
}
烦恼的高考志愿
P1678 烦恼的高考志愿原题链接
直接调用set中的lower_bound函数,找到大于等于考试分的院校分数线。
再it–,取到它的前一位。两者对比求最小值
STL
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int m, n;
set<int> s;
int main() {
cin >> m >> n;
for (int i = 0; i < m; i++) {
int x;
scanf("%d", &x);
s.insert(x);
}
int ans = 0;
while(n--) {
int score;
scanf("%d", &score);
auto it = s.lower_bound(score);
int b = *it;
if (it != s.begin()) it--;
int a = *it;
int temp = abs(b-score) < abs(a-score) ? abs(b-score):abs(a-score);
ans += temp;
}
cout << ans;
return 0;
}
二分
如果不记得STL,就无法做了吗???
STL只是工具,也是人实现的,就拿lower_bound来说,本质就是二分
自己在考场上仍然需要静下心来,戒骄戒躁
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int m, n;
int s[N];
int main() {
cin >> m >> n;
for (int i = 0; i < m; i++)
scanf("%d", &s[i]);
sort(s, s+m);
int ans = 0;
while(n--) {
int score;
scanf("%d", &score);
int l = 0, r = m;
int temp = 1e9;
while(l < r) {
int mid = l + r >> 1;
if (s[mid] >= score) {
r = mid;
temp = min(temp, abs(s[mid] - score));
} else l = mid + 1;
}
if (score > s[m-1]) temp = abs(score - s[m-1]);
if (score < s[0]) temp = abs(s[0] - score);
if (r > 0)
temp = min(temp, abs(s[r-1] - score));
ans+= temp;
}
cout << ans;
return 0;
}