P2073 送花
对应章节:一、C++ 语法基础 → (十五) STL:容器、迭代器与算法。
(一) 任务与输出目标
按价格插入花、删除最贵或最便宜的花,结束时输出美丽值总和与价格总和。
(二) 建模与推导
map 以价格为键、美丽值为值;价格唯一,emplace 的结果能说明本次花是否加入。只有成功插入才增加两个总和。最便宜是 begin,最贵是 prev(end);删除前从总和减去对应字段,再移除记录。
(三) 手算与过程
加入 (美丽值5,价格10)、(8,20),再删除最贵,剩余总和为 5、10;重复价格的新花不会改变总和。
(四) 带注释实现
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve() {
map<int, int> flowers;
int beauty = 0, cost = 0;
int op;
while (cin >> op && op != -1) {
if (op == 1) {
int w, c;
cin >> w >> c;
if (flowers.emplace(c, w).second) {
beauty += w;
cost += c;
} // 重复价格不加入。
} else if (!flowers.empty()) {
auto it = op == 2 ? prev(flowers.end()) : flowers.begin();
cost -= it->first;
beauty -= it->second;
flowers.erase(it); // 总和与实际记录同步修改。
}
}
cout << beauty << ' ' << cost << '\n';
}
signed main() {
ios::sync_with_stdio(false); // 关闭同步,使用 cin 与 cout 完成输入输出。
cin.tie(0), cout.tie(0);
int T = 1; // 本题读入一组数据。
// cin >> T; // 题目给出测试组数时开启,并在 solve 中处理一组。
while (T--)
solve();
}(五) 复杂度
m 次操作时间 \(O(m\log m)\),空间 \(O(m)\)。